Search
🌱

AOP와 Proxy

Advisor = @Aspect = Advice + PointCut

JDK Dynamic Proxy

Proxy 객체 - Invocation Handler 를 변수로 가진다
reflection 을 이용
캐스팅된 객체에 메서드를 실행하면 Proxy 의 invoke 가 먼저 반응(Proxy -1 행 실행)

문제점

interface 가 반드시 존재해야한다
어떠한 시점에서 반드시 interface 로서 호출되어야 한다.
reflection 이라서 무겁다.
invoke 메서드가 상당히 제한적이다.

CGLIB

ProxyFactoryBean vs Enhancer
EnhancerBySpringCGLIB vs EnhancerByCGLIB
implements 하는 MethodInterceptor 가 다르다
org.aopalliance.intercept.MethodInterceptor;
org.springframework.cglib.proxy;
@Transactional 의 프록시들은 대부분 EnhancerBySpringCGLIB or Dynamic Proxy(interface 가 있는 애들) 이다.

ProxyFactoryBean

Aop 가 걸린 Bean을 등록할 때 등록된다.
해당 객체의 메서드가 호출될 때 CGLIB 객체의 메서드가 호출되고(-1행)
DynamicAdvisedInterceptor 가 동작한다. 얘가 등록된 advisor 들 실행시킨다.
advisor 를 강제하는 것 같다 → 이는 추후에 차차 알아보자!

AspectJ

implementation group: 'org.springframework', name: 'spring-aop', version: '5.2.22.RELEASE'
안통함
Bean named 'userService' is expected to be of type 'aop.stage2.UserService' but was actually of type 'com.sun.proxy.$Proxy71’
이 에러 계속 남
UserService 는 @Component 붙인 클래스
aop 관련 implementation 함
Component 는 EnhancerBySpringCglib 이다.
AspectJ: AOP 기술의 원조, 가장 강력한 AOP 프레임워크
AspectJ 자체는 Proxy 를 사용하지 않는다.
스프링도 AspectJ 의 포인트컷 표현식을 차용해서 사용
프록시 방식보다 강력하고 유연한 AOP 가 가능
오브젝트 생성, 필드 값의 조회와 조작, 스태틱 초기화 등 다양한 작업에 부가 기능을 부여
Service 는 CGLIB, Repository 는 JDK Dynamic Proxy!
이유는 Proxy 생성시 if 절에 interface 가 있는지 확인함. 있으면 JDK Dynamic Proxy 로 생성해버림
근데 JDK Dynamic Proxy 이다. 그래서 얘도 invoke handler 가 아니고 advisor 로 돈다.

@Transactional

ProxyFactoryBean 으로 생성된 SpringCGLIB 을 이용한다
advisor 는 BeanFactoryTransactionAttributeSourceAdvisor
advice 는 TransactionInterceptor
pointcut 은 TransactionAttributeSourcePointcut