spring 源碼分析 代理工廠 (ProxyFactory)

在之前spring aop解析中提到代理,是通過BeanPostProcessor 處理器來創建代碼, 那麼它是如何來創建代理的呢,採用的代理是動態代理還是靜態代理呢,這裏我繼續分析.
createProxy()方法
創建ProxyFactory 對象設置其屬性,這裏分三步:a、賦值默認屬性 b、獲取所有Advisor 的實現給代理工廠, 並把代理的對象給賦值給代理工廠 c、根據ClassLoader 類加載器創建代理.

ProxyFactory 代理工廠, 類結構圖

ProxyFactory

代理工廠, 類層次.
1、通過class加載器創建代理對象(ProxyFactory).
2、創建代理工廠 支持 (ProxyCreatorSupport)
3、儲存要代理的對象和Advisor 集合、接口class集合(AdvisedSupport)
4、代理配置類(ProxyConfig)

proxyFactory.getProxy(ClassLoader);
深入解析

	/**
	 * see org.springframework.aop.framework.ProxyFactory
	 * 創建AopProxy, 並通過類加載器獲取代理
	 */
	public Object getProxy(@Nullable ClassLoader classLoader) {
		return createAopProxy().getProxy(classLoader);
	}
	
	/**
	 * see org.springframework.aop.framework.ProxyCreatorSupport
	 * 獲取Aop代理工廠, 創建Aop代理.  這裏創建的AopProxyFactory,默認實現是DefaultAopProxyFactory
	 */
	protected final synchronized AopProxy createAopProxy() {
		if (!this.active) {
			activate();
		}
		return getAopProxyFactory().createAopProxy(this);
	}

	/**
	 * see org.springframework.aop.framework.ProxyCreatorSupport (創建類)
	 * 返回這個ProxyConfig使用的AopProxyFactory
	 */
	public AopProxyFactory getAopProxyFactory() {
		return this.aopProxyFactory;
	}

	/**
	 * see org.springframework.aop.framework.ProxyCreatorSupport 
	 * 創建一個新的ProxyCreatorSupport實例
	 */
	public ProxyCreatorSupport() {
		this.aopProxyFactory = new DefaultAopProxyFactory();
	}


aop代理工廠默認實現

org.springframework.aop.framework.DefaultAopProxyFactory
	/**
	 * 創建Aop代理, 默認使用Jdk動態代理(JdkDynamicAopProxy、CglibAopProxy)
	 */
	@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("error");
			}
			//代理對象如果是接口, 或者是代理類. 採用Jdk動態代理
			if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
				return new JdkDynamicAopProxy(config);
			}
			return new ObjenesisCglibAopProxy(config);
		}
		else {
			return new JdkDynamicAopProxy(config);
		}
	}

AopProxy 接口在spring中只有二種實現方法, 一種JdkDynamicAopProxy 代理, 一種AopCglibAopProxy 代理
二種不同代理執行效率比較:
一、原理區別:

java動態代理是利用反射機制生成一個實現代理接口的匿名類,在調用具體方法前調用InvokeHandler來處理。

而cglib動態代理是利用asm開源包,對代理對象類的class文件加載進來,通過修改其字節碼生成子類來處理。

1、如果目標對象實現了接口,默認情況下會採用JDK的動態代理實現AOP
2、如果目標對象實現了接口,可以強制使用CGLIB實現AOP

3、如果目標對象沒有實現了接口,必須採用CGLIB庫,spring會自動在JDK動態代理和CGLIB之間轉換

如何強制使用CGLIB實現AOP?
(1)添加CGLIB庫,SPRING_HOME/cglib/*.jar
(2)在spring配置文件中加入<aop:aspectj-autoproxy proxy-target-class=“true”/>

JDK動態代理和CGLIB字節碼生成的區別?
(1)JDK動態代理只能對實現了接口的類生成代理,而不能針對類
(2)CGLIB是針對類實現代理,主要是對指定的類生成一個子類,覆蓋其中的方法
因爲是繼承,所以該類或方法最好不要聲明成final

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