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