티스토리 뷰
Spring AOP는 JDK 동적 프록시
또는 CGLIB
를 사용하여 지정된 대상 객체에 대한 프록시를 만듭니다.
JDK 동적 프록시 java의 리플렉션을 이용해서 객체를 만든다. CGLIB 경우에는 바이트코드를 조작해 프록시 객체를 만든다.
Spring boot 는 기본적으로 transaction 대상의 aop를 동작시킬 프록시를 cglib 프록시를 사용하게 설정 해놨다.
그리고 성능 또한 jdk 프록시보다는 cglib가 빠르다. 우리가 느낄정도? 아니지만 일반적으로 cglib가 예외를 발생시킬 가능성이 낮다고 한다.
프록시 할 대상 객체가 하나 이상의 인터페이스를 구현하는 경우 JDK 동적 프록시가 사용됩니다.타겟 타입에 의해 구현 된 모든 인터페이스는 프록시 화됩니다.대상 객체가 인터페이스를 구현하지 않으면 CGLIB 프록시가 생성됩니다.
CGLIB 프록시 (예를 들어, 인터페이스에 의해 구현 된 것뿐만 아니라 대상 클래스에 대해 정의 된 모든 메소드를 프록시하는 경우)를 사용하도록 강제 할 수 있습니다. 그러나 고려해야 할 몇 가지 문제가 있습니다.
- 클래스 프록시는 final 클래스에는 적용할 수 없다. 클래스 프록시는 타깃 클래스를 상속해서 프록시를 만드는 방법을 사용하기 때문에 상속이 불가능한 final 클래스에는 적용되지 않는다.
- 클래스 패스에는 CGLIB 2바이너리가 필요하지만 동적 프록시는 JDK에서 사용할 수 있습니다. CGLIB가 필요하고 CGLIB 라이브러리 클래스가 클래스 경로에서 발견되지 않으면 Spring은 자동으로 경고를 보낸다.
- 프록시 객체의 생성자는 두 번 호출됩니다. 이것은 CGLIB프록시 모델의 자연스러운 결과로서 프록시 된 각 객체에 대해 하위 클래스가 생성됩니다. 각 프록시 인스턴스의 경우 두개의 오브젝트(실제 프록시 오브젝트)가 작성됩니다. 이 동작은 JDK 프록시를 사용할 때 표시 되지 않습니다. 일반적으로 프록시 유형의 생성자를 두 번 호출하는 것은 문제가되지 않습니다. 일반적으로 할당 만 수행되고 실제 논리는 생성자에서 구현되지 않기 때문에 문제가 아니다.
강제로 CGLIB 프록시를 사용하려면 요소의 proxy-target-class 속성 값을 true로 설정
<aop:config proxy-target-class="true">
@AspectJ 자동 프록시 지원을 사용할 때 강제로 CGLIB 프록시를 사용하려면 요소의 'proxy-target-class'속성을 true로 설정
<aop:aspectj-autoproxy proxy-target-class="true"/>
spring-boot properties 아래와 같이 설정
spring.aop.proxy-target-class=true
'Spring' 카테고리의 다른 글
Restful API 버전관리 (2) | 2019.10.25 |
---|---|
Spring ApplicationEvent (0) | 2019.10.10 |
HandlerMethodArgumentResolver (0) | 2019.10.02 |
IoC란 (0) | 2019.04.24 |
스프링에서 @Async로 비동기처리하기 (0) | 2017.04.21 |