AOP 中 ProxyFactory
的子類有 ProxyCreatorSupport
、AdvisedSupport
、ProxyConfig
。其中核心是 ProxyCreatorSupport
,此類主要初始化了具體動態代理方案。其他 AdvisedSupport
、ProxyConfig
主要是圍繞 AOP 相關配置進行封裝。
ProxyFactory 基本涵蓋了 Spring AOP 的基本實現。瞭解完成 ProxyFactory 後可以進入瞭解 ProxyFactoryBean,ProxyFactoryBean 進而結合 FactoryBean[1] 功能可以方便使用已經註冊在容器內部的實現類。
1. 初始化 ProxyFactory
初始化時,ProxyCreatorSupport 默認構造函數初始化了一個默認的 AopProxyFactory [2],此 AopProxyFactory 主要是依據不同的條件下面去使用 JDK 還是 CGLib 的動態代理。
public class ProxyCreatorSupport extends AdvisedSupport {
private AopProxyFactory aopProxyFactory;
...
/**
* Create a new ProxyCreatorSupport instance.
*/
public ProxyCreatorSupport() {
this.aopProxyFactory = new DefaultAopProxyFactory();
}
...
}
2. 設置代理相關配置
//這目標對象
ProxyFactory.setTarget(Object target);
//設置切面
ProxyFactory.addAdvice(Advice advice);
3. 獲取代理對象 ProxyFactory#getProxy()
ProxyFactory#getProxy() 其實就是調用了 ProxyFactory#createAopProxy(),這裏就是調用DefaultAopProxyFactory#createAopProxy(AdvisedSupport config) ,設置代理相關參數和返回AopProxy。
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
再調用 AopProxy#getProxy() 方法返回真正的對象。到這裏,表面那一層的調用說明這裏即可。
4. AopProxy
4.1 JdkDynamicAopProxy
使用 JdkDynamicAopProxy 動態代理的話,只能代理接口類。JDK的動態代理主要是實現 InvocationHandler 接口。
public interface InvocationHandler {
//調用接口裏面的方法時,就會調用以下方法
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
}
也就是說核心在 JdkDynamicAopProxy#invoke(Object proxy, Method method, Object[] args) 方法。而判斷那些方法需要增強的判斷在
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
這裏巧妙利用攔截器的個數來控制是否需要調用 Advice。這也就是爲什麼JDK的動態代理運行比較慢,是需要在 invoke 裏面進行過濾執行。
假如需要自定義判斷處理邏輯自己實現 AdvisorChainFactory 後,調用
AdvisedSupport#setAdvisorChainFactory(AdvisorChainFactory advisorChainFactory)
設置。
5. AOP 基礎
5.1 Advice 通知
具體做事情的類,也就是說你需要如何做或者做什麼,都在 Advice 裏面實現,目前常用的有
- AfterReturningAdvice:方法執行後運行
- MethodBeforeAdvice:方法調用前執行
- ThrowsAdvice:出現異常後調用。
5.2 Pointcut
定義什麼樣的東西需要被攔截。比如說以 get 開頭我就攔截。常用有:
- NameMatchMethodPointcut:通過名稱
- AspectJExpressionPointcut:通過使用一套表達式
5.3 Advisor
Advisor = Advice + Pointcut。常用有:
- AspectJExpressionPointcutAdvisor
- NameMatchMethodPointcutAdvisor
6. 總結
在AOP構建主線的過程中,提供了很多擴展的空間。比如:
- AopProxyFactory:如果不滿足現在有的 JDK和CGLib 的動態代理實現,可以自定義實現。
- AdvisedSupportListener:可以註冊監聽動作
- AdvisorChainFactory:在具體實現調用增強的時候可以進行優化
使用的註解有:
//標記爲切面類
@Aspect
//攔截點
@Pointcut
//前置
@Before
//後置
@After
//環繞
@Around
7. 註釋
[1]:支持使用已經註冊到IoC容器的相關類,包括配置,切面等。
[2]:默認實現 DefaultAopProxyFactory,如果有其他的動態代理實現方式,可以去實現 接口 AopProxyFactory
,然後使用 ProxyCreatorSupport#setAopProxyFactory(AopProxyFactory aopProxyFactory)
。