AOP를 빈으로 등록할 때는 보통 config파일에서 @Bean으로 등록을 하게된다.
이 때 아래와 같은 순환참조가 발생할 수 있는데 그 이유과 해결방법에 대해 얘기해본다.
The dependencies of some of the beans in the application context form a cycle:
@Aspect
public class TimeTraceAop {
@Around("execution(* hello.hellospring..*(..))")
public Object execute(ProceedingJoinPoint joinPoint) throws Throwable {
}
}
@Configuration
public class SpringConfig {
@Bean
public TimeTraceAop timeTraceAop() {
return new TimeTraceAop();
}
}
위와 같이 등록을 한 경우 순환참조가 발생하는 이유는 아래와 같다.
TimeTraceAop의 AOP대상을 지정하는 @Around코드를 보면, SpringConfig의 TimeTraceAOP()메서드도 AOP 대상에 포함이 되는데 문제는 이 코드가 바로 자기 자신인 TimeTraceAop를 생성하는 코드인 것이다. 그래서 순환 참조가 발생하는 것이다.
반면에 @Component를 사용하게되면 TimeTraceAOP()메서드 메서드가 AOP 대상에 포함이 되지 않는다.
AOP 대상에서 아래와 같이 @Around에 !target(hello.hellospring.SpringConfig)를 추가(패키지 포함 클래스명)해서 SpringConfig를 대상에서 제외하면 된다.
@Aspect
public class TimeTraceAop {
@Around("execution(* hello.hellospring..*(..)) && !target(hello.hellospring.SpringConfig)")
//@Around("execution(* hello.hellospring..*(..))")
public Object execute(ProceedingJoinPoint joinPoint) throws Throwable {...}
}