Spring ProxyFactory 詳細分析

AOP 中 ProxyFactory 的子類有 ProxyCreatorSupportAdvisedSupportProxyConfig。其中核心是 ProxyCreatorSupport,此類主要初始化了具體動態代理方案。其他 AdvisedSupportProxyConfig 主要是圍繞 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)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章