[Spring] AOP(관점 지향 프로그래밍)

rara_kim·2022년 8월 15일
0

Spring

목록 보기
3/20
post-thumbnail

AOP란?

  • Aspect Oriented Programming: 관점 지향 프로그래밍
  • 여러 객체에서 공통적으로 사용하고 있는 기능을 분리해서 모듈화하고 재사용하는 프로그래밍 기법
  • 핵심 기능과 공통 기능의 구현을 분리하여 핵심 기능의 코드 수정없이 공통 기능 적용 가능
  • 여러 클래스, 메소드에 공통적으로 나타나는 코드들을 Concern이라고 한다.
  • 각 클래스에 있는 Crosscutting Concerns(흩어진 관심사)를 Aspect로 모듈화하고 핵심적인 비즈니스 로직에서 분리하여 재사용하겠다는 것이 AOP의 취지이다.
  • AOP는 AOP의 구현체를 제공하며, 자바에 만들어져 있는 프레임워크 AspectJ라는 또 다른 구현체와 연동해서 사용할 수 있는 기능을 제공한다.
  • 대표적으로 인증, 트랜잭션 관리, 로깅 등과 같은 인프라 로직을 AOP로 처리한다.
  • 스프링은 프록시 기반 AOP를 지원한다.

각각의 색들을 Concern이라고 보면된다.
여기서 Concern이란 여러 클래스, 메서드에 걸쳐서 나타나는 비슷한 코드들을 의미한다.

각 클래스에 있는 Crosscutting Concerns, 흩어진 관심사를 Aspect로 모듈화하고 핵심적인 비즈니스 로직에서 분리하여 재사용하겠다는 것이 AOP의 취지이다.


AOP 적용방식

  • 컴파일 시점에 코드에 공통기능을 삽입
    • AOP 개발도구가 소스 코드를 컴파일 하기 전에 공통 구현 코드를 소스에 삽입하는 방식
    • AspectJ같은 AOP 전용도구를 사용해서 적용
  • 클래스 로딩 시점(로드 타임)에 바이트 코드에 공통 기능을 삽입
    • 클래스를 로딩할 때 바이트 코드에 공통 기능을 클래스에 삽입하는 방식
    • AspectJ 같은 AOP 전용 도구를 사용해서 적용
  • 런타임에 프록시 객체를 생성해서 공통 기능을 삽입
    • 프록시 객체를 생성하고 그 안에 실제 객체를 넣어 실제객체를 통해 핵심기능을 실행하고 공통 기능은 프록시 객체가 처리하는 방식
    • 스프링 AOP에서 지원
    • 스프링 AOP가 프록시 객체를 자동으로 생성하여 처리해주기 때문에 프록시 클래스를 직접 구현할 필요가 없다.
    • 개발자는 공통 기능을 구현한 클래스만 구현하면 된다.

Spring AOP 특징

  • 프록시 패턴 기반의 AOP 구현체
    • Target 객체에 대한 프록시를 만들어 제공
    • Target을 감싸는 프록시는 런타임 시 생성
    • 접근 제어 및 부가 기능 추가를 위해 프록시 객체 사용
  • 프록시가 Target 객체의 호출을 가로채 Advice 수행 전/후 핵심 로직 호출
  • 스프링 Bean에만 AOP 적용 가능
    • 메소드 조인 포인트만 지원하여 메소드가 호출되는 런타임 시점에만 Advice 적용 가능
  • 모든 AOP기능을 제공하지는 않으며 스프링 IoC와 연동하여 엔터프라이즈 애플리케이션의 각종 문제(중복 코드, 프록시 클래스 작성의 번거로움, 객체 간 관계 복잡도 증가)에 대한 해결책 지원 목적

AOP 프록시 동작방식

프록시 패턴

프록시 패턴에는 interface가 존재하고 Client는 이 interface 타입으로 Proxy 객체를 사용하게 된다.
Proxy 객체는 기존의 타겟 객체(Real Subject)를 참조하고 있다. Proxy 객체와 Real Subject의 타입은 같고, Proxy는 원래 해야 할 일을 가지고 있는 Real Subject를 감싸서 Client의 요청을 처리한다.


AOP 용어

Aspect(관점, 관심)

  • 여러 객체에 공통으로 적용되는 기능
  • @Transactional이나 @Cacheable, 보안 등이 좋은 예
  • 클래스 단위에서 @Aspect로 적용
  • Aspect 클래스 내부에는 Advice와 Point Cut이 들어간다.

Advice(조언)

  • AOP에서 실제로 적용하는 기능
  • 언제 공통 관심 기능을 핵심 로직에 적용할지를 정의
  • 실제로 적용할 기능을 작성한다.
  • 어노테이션에는 포인트컷을 알려줘야한다.
    • Before
      • 대상 객체의 메서드 호출 전에 공통 기능을 실행
    • After Returning
      • 대상 객체의 메서드가 익셉션 없이 실행된 이후에 공통기능을 실행
    • After Throwing
      • 대상 객체의 메서드를 실행하는 도중 익셉션이 발생한 경우에 공통기능을 실행
    • After
      • Exception 발생여부에 상관없이 대상객체의 메서드 실행 후 공통 기능 실행
      • try - catch -finally 에서 finally 와 유사
    • Around
      • 대상 객체 메서드 실행하기 전/후 , 익셉션 발생 시점 등 다양한 시점에 공통 기능 실행

Joinpoint(연결 포인트)

  • Advice를 적용될 위치, 끼어들 수 있는 지점
  • 생성자 호출 직전, 생성자 호출 시, 필드에 접근하기 전, 필드에서 값을 꺼낼 때 등
  • 스프링은 프록시를 이용해서 AOP를 구현하기 때문에 메서드 호출에 대한 Joinpoint만 지원한다.

Pointcut (포인트 선택방법)

  • 실제 Advice가 적용되는 Joinpoint
  • Joinpoint 중에서 해당 Aspect를 적용할 대상을 뽑을 조건식
  • 스프링에서는 정규표현식이나 AspectJ의 문법을 이용하여 Pointcut을 정의할 수 있다.
  • 여러 Aspect에서 공통으로 사용하는 Pointcut이 있다면 별도 클래스로 분리하는 것이 좋다.

Target Object

  • Advice가 적용될 대상(클래스, 메소드 등)

AOP Proxy

  • 대상 오브젝트에 Aspect를 적용하는 경우, Advice를 덧붙이기 위해 하는 작업을 의미
  • 주로 CGLIB(Code Generation Library, 실행 중에 실시간으로 코드를 생성하는 라이브러리) 프록시를 사용하여 프록싱 처리한다.

Weaving

  • Advice를 핵심 로직 코드에 적용하는 것


📚참고
스프링 AOP 총정리
Spring AOP(관점 지향 프로그래밍)
Spring:스프링AOP란? Aspect Oriented Programming

profile
느리더라도 꾸준하게

0개의 댓글