AOP 인터페이스를 만들고 연결을 시킬 때
1. Component 스캔 방법
2. 자바 코드로 직접 스프링 빈 등록
2가지 방법이 모두 가능하다고 했다. (중복 사용은 불가)
1번 방법 사용
@Aspect @Component public class TimeTraceAop { @Around("execution(* hello.hellospring..*(..))") //패키지 하위 클래스 모두에 적용 public Object execute(ProceedingJoinPoint joinPoint) throws Throwable{ long start = System.currentTimeMillis(); System.out.println("START: "+joinPoint.toString()); try{ return joinPoint.proceed(); }finally{ long finish = System.currentTimeMillis(); long timeMs = finish-start; System.out.println("END: "+joinPoint.toString()+" "+timeMs+"ms"); } } }
2번 방법 사용
@Bean public TimeTraceAop timeTraceAop(){ return new TimeTraceAop(); }
SpringConfig Class에 직접 주입
그런데 2번 방법을 사용하게 되면 순환 참조 오류가 발생함.
답변
@Around 코드를 보면 SpringConfig의 timeTraceAop() 메서드도 AOP로 처리하게 된다.
@Around("execution(* hello.hellospring..*(..))") //hello.hellospring 아래에 있는 모든 패키지에 적용을 한다.
바로 자기 자신인 TimeTraceAop를 생성하는 코드가 되어서 순환참조 문제가 발생한다.
반면에 컴포넌트 스캔을 할 때에는 AOP의 대상이 되는 이런 코드 자체가 없기 때문에 문제가 발생하지 않았다.
해결방법
@Around("execution(* hello.hellospring..*(..)) && !target(hello.hellospring.SpringConfig)")
SpringConfig는 제외하고 AOP를 처리하게 한다.