[스프링 핵심 원리 - 고급편] #15. 스프링 AOP - 실무 주의사항 #73
YONGHYNG
announced in
Announcements
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
프록시와 내부 호출 - 문제
CallServiceV0
CallServiceV0.external()을 호출하면 내부에서 internal() 이라는 자기 자신의 메서드를 호출한다.CallLogAspect
CallServiceV0Test
@Import(CallLogAspect.class): 앞서 만든 간단한 Aspect 를 스프링 빈으로 등록한다. 이렇게 해서, CallServiceV0 에 AOP 프록시를 적용한다.@Import(CallLogAspect.class): 앞서 만든 간단한 Aspect 를 스프링 빈으로 등록한다. 이렇게 해서,CallServiceV0 에 AOP 프록시를 적용한다.
실행 결과 - external()

실행 결과를 보면 callServiceV0.external() 을 실행할 때는 프록시를 호출한다. 따라서 CallLogAspect 어드바이스가 호출된 것을 확인할 수 있다. 그리고 AOP Proxy는 target.external() 을 호출한다.
그런데 여기서 문제는 callServiceV0.external() 안에서 internal() 을 호출할 때 발생한다. 이때는 CallLogAspect 어드바이스가 호출되지 않는다.
자바 언어에서 메서드 앞에 별도의 참조가 없으면 this 라는 뜻으로 자기 자신의 인스턴스를 가리킨다.
결과적으로 자기 자신의 내부 메서드를 호출하는 this.internal() 이 되는데, 여기서 this 는 실제 대상 객체
(target)의 인스턴스를 뜻한다. 결과적으로 이러한 내부 호출은 프록시를 거치지 않는다. 따라서 어드바이스도 적용할수 없다.
실행 결과 - internal()


할 수 있다.
참고
프록시와 내부 호출 - 대안1 자기 자신 주입
CallServiceV1
CallServiceV1Test
실행 결과


주의
스프링 부트 2.6부터는 순환 참조를 기본적으로 금지하도록 정책이 변경되었다. 따라서 이번 예제를 스프링 부트2.6 이상의 버전에서 실행하면 다음과 같은 오류 메시지가 나오면서 정상 실행되지 않는다.
Error creating bean with name 'callServiceV1': Requested bean is currently in creation: Is there an unresolvable circular reference?이 문제를 해결하려면 application.properties 에 다음을 추가해야 한다.
spring.main.allow-circular-references=true앞으로 있을 다른 테스트에도 영향을 주기 때문에 스프링 부트 2.6 이상이라면 이 설정을 꼭 추가해야 한다.
프록시와 내부 호출 - 대안2 지연 조회
CallServiceV2
CallServiceV2Test
실행 결과

프록시와 내부 호출 - 대안3 구조 변경
CallServiceV3
InternalService
CallServiceV3Test
실행 결과


참고
Beta Was this translation helpful? Give feedback.
All reactions