深入理解Spring AOP之二代理對象生成
深入理解Spring AOP之二代理對象生成
spring代理對象
上一篇博客中講到了Spring的一些基本概念和初步講了實現方法,當中提到了動態代理技術,包含JDK動態代理技術和Cglib動態代理
動態代理這部分我有過一篇博客介紹:動態代理,想深入了解的朋友能夠看一看,再回想一下,Spring中怎樣區分採用JDK動態代理和CGlib動態代理:
- 假設目標對象的實現類實現了接口。Spring AOP 將會採用 JDK 動態代理來生成 AOP 代理類;
- 假設目標對象的實現類沒有實現接口,Spring AOP 將會採用 CGLIB 來生成 AOP 代理類
將下載編譯好的Spring-aop包中的源代碼打開,例如以下圖所看到的
對應的源代碼能夠在Github上面。然後用工具編譯成project文件。再導入eclipse裏面來閱讀,網上有對應的方法。
Spring AOP 使用類 org.springframework.aop.framework.ProxyFactory進行織入。找到ProxyFactory相應的相關內容,然後整理例如以下類圖
Spring代理類怎樣生成
調用方法步驟能夠例如以下所看到的:
先看ProxyFactory是怎樣得到代理類的
public Object getProxy() {
return createAopProxy().getProxy();
}
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
實現它獲得一個用來產生代理的實例, createAopProxy() 方法返回 AopProxy, 然後再調用 getProxy() 方法產生詳細的代理對象,這裏以下再細講。由於在ProxyFactoryBean中也用到了一樣的父類。
ProxyFactoryBean是怎樣獲得代理類的
找到ProxyFactoryBean方法,ProxyFactoryBean是在Spring IoC環境中,創建AOP應用的最底層方法,從中。能夠看到一條實現AOP的基本線索。借助如上類圖,看看AOP代理類是怎樣產生的(回想下動態代理中的代理類生成方法)
為什麽要先看getObject方法呢:假設容器中的某個對象持有某個FactoryBean的引用,它取得的不是FactoryBean本身,而是FactoryBean的getObject()方法所返回的對象。
所以。假設容器中某個對象依賴於ProxyFactoryBean,那麽它將會使用到ProxyFactoryBean的getObject()方法所返回的代理對象
@Override
public Object getObject() throws BeansException {
initializeAdvisorChain(); //初始化通知器
if (isSingleton()) {
return getSingletonInstance();//依據定義生成單例的Proxy
}
else {
if (this.targetName == null) {
logger.warn("Using non-singleton proxies with singleton targets is often undesirable. " +
"Enable prototype proxies by setting the ‘targetName‘ property.");
}
return newPrototypeInstance(); //這裏依據定義生成prototype的Proxy
}
}
private synchronized Object getSingletonInstance() {
if (this.singletonInstance == null) {
this.targetSource = freshTargetSource();//返回被 代 理的 目標對象
if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {
//從targetSource中獲取目標對象的Class
Class<?> targetClass = getTargetClass();
if (targetClass == null) {
throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy");
}
//這裏設置代理對象的接口 setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));
}
// 初始化共享的單例
super.setFrozen(this.freezeProxy);
//這裏會使用ProxyFactory來生成須要的Proxy
this.singletonInstance = getProxy(createAopProxy());
}
return this.singletonInstance;
}
這裏看看setFrozen()和createAopProxy()方法,調用的是proxyFactoryBean上一層接口ProxyCreatorSupport中的方法(看類圖),
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this); //這裏借助了AopProxyFactory
}
以下這非常重要。getAopProxyFactory()方法,
public AopProxyFactory getAopProxyFactory() {
return this.aopProxyFactory;
}
盡管返回的是aopProxyFactory可是我們假設追蹤到構造函數中,我們發現其有用的是new DefaultAopProxyFactory();
private AopProxyFactory aopProxyFactory;
public ProxyCreatorSupport() {
this.aopProxyFactory = new DefaultAopProxyFactory();
}
繼續追蹤到DefaultAopProxyFactory中,找到createAopProxy()方法,最終真相大白,例如以下
@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);
}
}
能夠看到當中的代理對象能夠由JDK或者Cglib來生成的,JdkDynamicAopProxy類和Cglib2AopProxy都實現的是AopProxy的接口。上面的這些邏輯就是要推斷採用兩種動態代理中的那一種。詳細的規則能夠參考最上面的介紹。到了這裏。可能對JDK動態代理有點心動,畢竟動態代理中接觸過了,例如以下是JdkDynamicAopProxy中實現代理的方法-getproxy()方法
@Override
public Object getProxy(ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
}
//依據advised 中 的 配 置信息,將proxy須要代 理的接口放入proxiedInterfaces 中
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
//以下這種方法眼熟吧,哈哈 沒錯就是JDK中的動態代理經典方法
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
用Proxy包裝target之後,通過ProxyFactoryBean得到對其方法的調用就被Proxy攔截了, ProxyFactoryBean的getObject()方法得到的實際上是一個Proxy了,target對象已經被封裝了。對 ProxyFactoryBean這個工廠bean而言,其生產出來的對象是封裝了目標對象的代理對象
總結
上面講了怎麽多,簡單回想下代理對象是怎樣生成的
1、上面講到了兩種生成代理對象的方法,一種是通過ProxyFactory,一種是通過ProxyFactoryBean。
第一種獲取比較簡單。可是須要手工的進行寫代碼,而另外一種是通過Spring的IOC機制來控制Bean的生成。 2、不管是ProxyFactory或者ProxyFactoryBean都是要通過createAopProxy().getProxy()來獲取對應的代理對象,而通過Proxyfactory比較直接,上面重點介紹的是通過ProxyFactoryBean獲得proxy。 3、首先,找到ProxyFactoryBean的getObject方法。為什麽?(主要是跟Bean容器中getObject能返回代理對象) 4、其次調用getSingletonInstance()。在getSingletonInstance方法中引入了super中的方法,super是指ProxyCreatorSupport。這裏ProxyCreatorSupport是ProxyFactoryBean和ProxyFactory的父類,已經做了非常多工作,僅僅需在ProxyFactoryBean的getObject()方法中通過父類的createAopProxy()取得對應的AopProxy。 5、跟蹤createAopProxy方法。追蹤到了ProxyCreatorSupport中,然後,借助了AopProxyFactory,此時得到的aopProxyFactory,在構造函數中已經定義為new DefaultAopProxyFactory() 6、進入DefaultAopProxyFactory中。找到createAopProxy方法。在這裏推斷是調用JDK動態或者CGlib動態中的一種。
深入理解Spring AOP之二代理對象生成