深刻理解Spring AOP之二代理對象生成
spring代理對象
Spring AOP 使用類 org.springframework.aop.framework.ProxyFactory進行織入。找到ProxyFactory相應的相關內容,而後整理例如如下類圖java
Spring代理類怎樣生成
先看ProxyFactory是怎樣獲得代理類的
public Object getProxy() { return createAopProxy().getProxy(); } protected final synchronized AopProxy createAopProxy() { if (!this.active) { activate(); } return getAopProxyFactory().createAopProxy(this); }
ProxyFactoryBean是怎樣得到代理類的
因此。假設容器中某個對象依賴於ProxyFactoryBean,那麼它將會使用到ProxyFactoryBean的getObject()方法所返回的代理對象 git
@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; }
protected final synchronized AopProxy createAopProxy() { if (!this.active) { activate(); } return getAopProxyFactory().createAopProxy(this); //這裏藉助了AopProxyFactory }
public AopProxyFactory getAopProxyFactory() { return this.aopProxyFactory; }
private AopProxyFactory aopProxyFactory; public ProxyCreatorSupport() { this.aopProxyFactory = new DefaultAopProxyFactory(); }
github
@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); } }
@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); }
總結
第一種獲取比較簡單。但是需要手工的進行寫代碼,而另一種是經過Spring的IOC機制來控制Bean的生成。 spring