@Aspect AOP

현시기얌·2021년 11월 27일
0

AOP

목록 보기
9/19

@Aspect 프록시 적용

스프링 애플리케이션에 프록시를 적용하러면 포인트컷과 어드바이스로 구성되어 있는 Advisor를 만들어서 스프링 빈으로 등록하면 된다.
그러면 나머지는 자동 프록시 생성기가 모두 자동으로 처리해준다.
자동 프록시 생성기는 스프링 빈으로 등록된 Advisor들을 찾고, 스프링 빈들에 자동으로 프록시를 적용해준다.
(물론 포인트컷에 매칭되는 경우에 프록시를 생성한다.)

스프링은 @Aspect 애노테이션으로 매우 편리하게 포인트컷과 어드바이스로 구성되어 있는 어드바이저 생성 기느을 지원한다.

cf) 참고

@Aspect는 관점 지향 프로그래밍(AOP)을 가능하게 하는 AspectJ 프로젝트에서 제공하는 애노테이션이다.
스프링은 이것을 차용해서 프록시를 통한 AOP를 가능하게 한다.

예제 코드

@Slf4j
@Aspect
public class LogTraceAspect {

    private final LogTrace logTrace;

    public LogTraceAspect(LogTrace logTrace) {
        this.logTrace = logTrace;
    }

    @Around("execution(* hello.proxy.app..*(..))")
    public Object execute(ProceedingJoinPoint joinPoint) throws Throwable {
        TraceStatus status = null;
        try {
            final String message = joinPoint.getSignature().toShortString();
            status = logTrace.begin(message);

            //로직 호출
            final Object result = joinPoint.proceed();
            logTrace.end(status);
            return result;
        } catch (Exception e) {
            logTrace.exception(status, e);
            throw e;
        }
    }
}

@Configuration
public class AopConfig {

    @Bean
    public LogTraceAspect logTraceAspect(LogTrace logTrace) {
        return new LogTraceAspect(logTrace);
    }
}
  • @Aspect : 애노테이션 기반 프록시를 적용할 때 필요하다.
  • @Around("execution( hello.proxy.app..(..))")
    • @Around의 값에 포인트컷 표현식을 넣는다. 표현식은 AspectJ 표현식을 사용한다.
    • @Around의 메소드는 Advice가 된다.
  • ProceedingJoinPoint joinpoint : Advice에서 살펴본 MethodInvocation invocation과 유사한 기능이다.
    • 내부에 실제 호출 대상, 전달 인자, 그리고 어떤 객체와 어떤 메소드가 호출되었는지 정보가 포함되어 있다.
  • joinPoint.proceed() : 실제 호출 대상(target)을 호출한다.

@Aspect 프록시

자동 프록시 생성기는 Advisor를 자동으로 찾아와서 필요한 곳에 프록시를 생성하고 적용해준다.
자동 프록시 생성기는 추가로 하나의 역할 더 하는데 바로 @Aspect를 찾아서 이것을 Advisor로 만들어준다.
쉽게 말해서 @Aspect를 Advisor로 변환해서 저장하는 기등도 한다.

자동 프록시 생성기는 2가지 일을 한다.

  1. @Aspect를 보고 Advisor로 변환해서 저장한다.
  2. Advisor를 기반으로 프록시를 생성한다.

1. @Aspect를 Advisor로 변환해서 저장하는 과정

  1. 실행 : 스프링 애플리케이션 로딩 시점에 자동 프록시 생성기를 호출한다.
  2. 모든 @Aspect 빈 조회 : 자동 프록시 생성기는 스프링 컨테이너에서 @Aspect 애노테이션이 붙은 스프링 빈을 모두 조회한다.
  3. Advisor 생성 : @Aspect 어드바이저 빌더를 통해 @Aspect 애노테이션 정보를 기반으로 Advisor를 생성한다.
  4. @Aspect 기반 Advisor 저장 : 생성한 Advisor를 @Aspect 어드바이저 빌더 내부에 저장한다.

@Aspect 어드바이저 빌더

BeanFactoryAsepctJAdvisorBuilder 클래스이다.
@Aspect의 정보를 기반으로 Pointcut, Advice, Advisor를 생성하고 보관하는 것을 담당한다.
@Aspect의 정보를 기반으로 Advisor를 만들고
@Aspect 어드바이저 빌더 내부 저장소에 캐시한다.
캐시에 Advisor가 이미 만들어져 있는 경우 캐시에 저장된 Advisor를 반환한다.

2. Advisor를 기반으로 프록시 생성

1 생성 : 스프링 빈 대상이 되는 객체를 생성한다. (Bean, 컴포넌트 스캔 모두 포함)
2. 전달 : 생성된 객체를 빈 저장소에 등록하기 직전에 빈 후처리기에 전달한다. (자동 프록시 생성기)
3-1. Advisor 조회 : 스프링 컨테이너에서 Advisor 빈을 모두 조회한다.
3-2. @Aspect Advisor 조회 : @Aspect 어드바이저 빌더 내부에 저장된 Advisor를 모두 조회한다.
4. 프록시 적용 대상 체크 : 앞서 3-1,3-2에서 조회한 Advisor에 포함되어 있는 포인트컷을 사용해서 해당 객체가 프록시를 적용할 대상인지 아닌지 판단한다.
이 때 객체의 클래스 정보는 물론이고 해당 객체의 모든 메소드를 포인트컷에 하나하나 모두 매칭해본다.
그래서 조건이 하나라도 만족하면 프록시 적용대상이 된다.
5. 프록시 생성 : 프록시 적용 대상이면 프록시를 생성하고 프록시를 반환한다. 그 프록시를 스프링 빈으로 등록한다.
만약 프록시 적용 대상이 아니라면 원본 객체를 반환해서 스프링 빈으로 등록한다.

정리

@Aspect를 사용해서 애노테이션 기반 프록시를 만들 수 있다.

profile
현시깁니다

0개의 댓글