Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

개발자되기 프로젝트

[@AspectAOP] @Aspect 프록시 - 적용 본문

인프런/[인프런] 스프링 핵심 원리 - 고급

[@AspectAOP] @Aspect 프록시 - 적용

Seung__ 2022. 1. 3. 23:32

1. @Aspect 프록시 - 적용


  • 스프링 애플리케이션에 프록시를 적용하려면 포인트컷과 어드바이스로 구성되어 있는 어드바이저
    ( Advisor )를 만들어서 스프링 빈으로 등록하면 된다. 
  • 그러면 나머지는 앞서 배운 자동 프록시 생성기가 모두 자동으로 처리해준다. 
  • 자동 프록시 생성기는 스프링 빈으로 등록된 어드바이저들을 찾고, 스프링 빈들에 자동으로 프록시를 적용해준다. 
    (물론 포인트컷이 매칭되는 경우에 프록시를 생성한다.)
  • 스프링은 @Aspect 애노테이션으로 매우 편리하게 포인트컷과 어드바이스로 구성되어 있는 어드바이저
    생성 기능을 지원한다.
  • 지금까지 어드바이저를 직접 만들었던 부분을 @Aspect 애노테이션을 사용해서 만들어보자.

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

 

2. 적용


@Slf4j
@Aspect
public class LogTraceAspect {

    private final LogTrace logTrace;

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

    @Around("execution(* hello.proxy.app..*(..))") //point cut
    public Object execute(ProceedingJoinPoint joinPoint) throws Throwable{
        //advice 로직

        TraceStatus status = null;
        try{
            String message = joinPoint.getSignature().toShortString(); //joint point의 signature 반환.
            status = logTrace.begin(message);

            //로직 호출
            Object result = joinPoint.proceed();
            logTrace.end(status);

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

 

3. Config


@Slf4j
@Configuration
@Import({AppV1Config.class, AppV2Config.class})
public class AopConfig {

    @Bean
    public LogTraceAspect logTraceAspect(LogTrace logTrace){
        return new LogTraceAspect(logTrace);
    }
}
  • @Import({AppV1Config.class, AppV2Config.class})
    V1, V2 애플리케이션은 수동으로 스프링 빈으로 등록해야 동작한다.
  • @Bean logTraceAspect()
    @Aspect 가 있어도 스프링 빈으로 등록을 해줘야 한다. 
    물론 LogTraceAspect 에 @Component 애노테이션을 붙여서 컴포넌트 스캔을 사용해서 스프링 빈으로 등록해도 됨
  • noLog() 호출 시 로그가 남지 않도록 표현식을 수정해주자.
@Around("execution(* hello.proxy.app..*(..)) && !execution(* hello.proxy.app..noLog(..))") //point cut

 

4. 실행


@Import(AopConfig.class)
@SpringBootApplication(scanBasePackages = "hello.proxy.app") //주의
public class ProxyApplication {

    public static void main(String[] args) {
        SpringApplication.run(ProxyApplication.class, args);
    }

    @Bean
    public LogTrace logTrace(){
        return new ThreadLocalLogTrace();
    }

}
  • 의도한 대로 정상 작동한다.

 

5. GitHub : 220103 @Aspect Proxy 1


 

GitHub - bsh6463/Spring_Advanced_2

Contribute to bsh6463/Spring_Advanced_2 development by creating an account on GitHub.

github.com

 

Comments