메서드의 시간을 측정하는 AOP를 작성하고 SpringConfig
에 빈을 등록하니 다음과 같이 순환 참조 에러가 발생하였다.
Relying upon circular references is discouraged and they are prohibited by default.Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.
에러 메세지대로 application.properties
에 spring.main.allow-circular-references=true
로 설정을 해주었지만 여전히 해결되지 않았다.
신기한 점은 SpringConfig
말고, @Component
어노테이션으로 컴포넌트 스캔을 이용하면 에러 없이 잘 동작한다는 것이다.
문제가 무엇인고 하니, AOP의 적용 범위를 지정해주는 부분에서 순환 참조를 발생시키고 있었다.
// 변경 전
@Aspect
public class TimeTraceAop {
@Around("execution(* hello.hellospring..*(..))")
public Object execute(ProceedingJoinPoint joinPoint) throws Throwable { }
}
해당 클래스의 경로는 hello.hellospring.aop
이다. 그런데 aop의 대상이 hello.hellospring
하위 모든 패키지 및 파일이다보니, 그 적용 대상에 자기 자신도 포함이 되어버려 순환 참조가 발생하는 것이다.
컴포넌트 스캔시에는 AOP 대상이 되는 이런 코드가 없기 때문에 문제가 발생하지 않는 것이다.
// 변경 후
@Aspect
public class TimeTraceAop {
@Around("execution(* hello.hellospring..*(..)) && !target(hello.hellospring.SpringConfig)")
public Object execute(ProceedingJoinPoint joinPoint) throws Throwable { }
}
위와 같이 변경 후 다시 실행하면 문제 없이 잘 동작한다!