深入理解Spring AOP之二代理对象生成
2017-06-12 21:02
561 查看
深入理解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相应的相关内容,然后整理例如以下类图
[p]
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中也用到了一样的父类。
[p]
[/p][p]
[/p] 找到ProxyFactoryBean方法,ProxyFactoryBean是在Spring IoC环境中,创建AOP应用的最底层方法,从中。能够看到一条实现AOP的基本线索。借助如上类图,看看AOP代理类是怎样产生的(回想下动态代理中的代理类生成方法)ProxyFactoryBean是怎样获得代理类的
为什么要先看getObject方法呢:假设容器中的某个对象持有某个FactoryBean的引用,它取得的不是FactoryBean本身,而是FactoryBean的getObject()方法所返回的对象。
所以。假设容器中某个对象依赖于ProxyFactoryBean,那么它将会使用到ProxyFactoryBean的getObject()方法所返回的代理对象 [p]
@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 } }[/p]
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<?[p] 能够看到当中的代理对象能够由JDK或者Cglib来生成的,JdkDynamicAopProxy类和Cglib2AopProxy都实现的是AopProxy的接口。上面的这些逻辑就是要推断採用两种动态代理中的那一种。详细的规则能够參考最上面的介绍。到了这里。可能对JDK动态代理有点心动,毕竟动态代理中接触过了,例如以下是JdkDynamicAopProxy中实现代理的方法-getproxy()方法 [/p]> 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); }
用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之二代理对象生成
- 深入理解SpringAOP之代理对象
- Spring AOP源码分析(生成代理对象)
- spring生成代理对象的过程(AOP切面)
- ######【spring属性注入(Ioc的DI)总结】:注解方式属性注入,属性名任意.=for理解:Aop注入代理对象时,注入被增强类对象时,属性名为proxy(自定义)。
- Spring AOP 代理对象的生成 part3
- Spring学习第二天Aop_invoke的代理对象生成解析
- Spring进阶之路(10)-Advice简介以及通过cglib生成AOP代理对象
- Spring进阶之路(9)-Spring AOP面向切面编程概念以及通过JDK代理生成AOP代理对象
- spring添加<aop:aspectj-autoproxy>让注解自为类生成代理对象时出错
- 深入理解Spring 之 源码剖析 SpringBoot Aop 切面编织过程和代理执行过程
- Spring:AOP(一)生成代理对象
- 【Spring源码--AOP的实现】(一)AopProxy代理对象的创建
- Spring Aop原理分析(一) - 建立AopProxy代理对象
- 深入理解Java对象实例生成的例子!
- Java基础---Java---基础加强---类加载器、委托机制、AOP、 动态代理技术、让动态生成的类成为目标类的代理、实现Spring可配置的AOP框架
- Spring源码阅读4.2-Aspecjt AOP之代理对象的创建
- Spring - 动态代理 与 AOP 理解
- 深入理解Spring AOP之基本概念