20.08.05 17:54 작성
·
3.5K
40
안녕하세요. 김영한 팀장님,
AOP(TimeTraceAop)를 @Component로 선언하지 않고
SpringConfig에 @Bean으로 등록할 수 있다고 설명하셨는데 실제로 코드를 돌려보면 빈 순환 참조 에러가 발생합니다.
강의대로 @Component로만 선언하면 문제가 없는데
왜 순환참조가 나는지 질문드립니다.
감사합니다.
The dependencies of some of the beans in the application context form a cycle:
memberController defined in file [~~~\out\production\classes\com\example\springexample\controller\MemberController.class]
↓
memberService defined in class path resource [com/example/springexample/SpringConfig.class]
┌─────┐
| timeTraceAop defined in class path resource [com/example/springexample/SpringConfig.class]
답변 11
98
2020. 08. 05. 23:07
안녕하세요. raifado님 좋은 질문입니다.
직접 @Bean으로 등록했을 때 순환참조가 발생하는 이유는 다음과 같습니다.
@Configuration
public class SpringConfig {
@Bean
public TimeTraceAop timeTraceAop() {
return new TimeTraceAop();
}
}
@Aspect
public class TimeTraceAop {
@Around("execution(* hello.hellospring..*(..))")
public Object execute(ProceedingJoinPoint joinPoint) throws Throwable { }
}
TimeTraceAop의 AOP 대상을 지정하는 @Around 코드를 보시면, SpringConfig의 timeTraceAop() 메서드도 AOP로 처리하게 됩니다. 그런데 이게 바로 자기 자신인 TimeTraceAop를 생성하는 코드인 것이지요. 그래서 순환참조 문제가 발생합니다.
반면에 컴포넌트 스캔을 사용할 때는 AOP의 대상이 되는 이런 코드 자체가 없기 때문에 문제가 발생하지 않았습니다.
그러면 AOP 설정 클래스를 빈으로 직접 등록할 때는 어떻게 문제를 해결하면 될까요? 바로 다음과 같이 AOP 대상에서 SpringConfig를 빼주면 됩니다.
@Aspect
public class TimeTraceAop {
@Around("execution(* hello.hellospring..*(..)) && !target(hello.hellospring.SpringConfig)")
//@Around("execution(* hello.hellospring..*(..))")
public Object execute(ProceedingJoinPoint joinPoint) throws Throwable {...}
}
도움이 되셨길 바래요^^
5
스프링부트 2.1 부터는 overriding 옵션이 false로 default 설정이 된다고 하네요.
https://n1tjrgns.tistory.com/172
SpringConfig.java에서 "@Bean public TimeTraceAop" 만들 때는
"@Component public class TimeTraceAop " 여기서 추가로 Bean이
중복 생성되므로 둘 중 한쪽 Bean은 제거해야 합니다.
("스프링입문_강의자료.pdf" 의 61쪽에 "@Component @Aspect public class TimeTraceAop" 만 있고 SpringConfig.java에 "@Bean public TimeTraceAop" 을 생성하지 않았네요. )
SpringConfig.java에서 "@Bean public TimeTraceAop" 사용하려면 @Component 삭제 하거나
application.properties의
spring.main.allow-bean-definition-overriding=true
추가 하면 된다고 하네요.
1
0
0
0
0
0
0
0
0
2022. 07. 27. 03:16
감사합니다!!