Spring AOP 代理对象的生成 part3
2016-07-05 23:39
477 查看
这一节我们探究一下在Spring AOP中目标对象的代理对象的生成过程。
我们会设计到三个主要的类:
ProxyFactoryBean
ProxyCreatorSupport
AdvisedSupport
从上到下时继承的关系。为便于区分我们称之为子类ProxyFactoryBean,父类ProxyCreatorSupport和祖类AdvisedSupport。
生成代理对象过程从子类ProxyFactoryBean开始的。
这个一个FactoryBean,我们会在配置文件中配置这个bean,通过这个bean获取代理对象的。因为的他名字就是代理工厂Bean。
获取代理对象是通过getObject方法,我们把对目标对象的增强都封装在了这个方法中。
在这个方法开始的时候,有一个方法initializeAdvisorChain,这个是用来初始化通知器链的方法。
一、初始化通知器链的过程
在初始化通知器链的过程时,spring会读取配置文件,获得通知器链的名字,然后根据名字,通过getBean方法,获得它的实例。
然后将实例保存起来,具体的保存时通过下面的这个方法:
主要调用的方法就是addAdvisor(advisor);很简单。
不过这个方法是祖类AdvisedSupport中定义的。
AdvisedSupport中有一个Linkedlist属性,用于存放通知器。它是私有的。
此时就将通知器保存进了AdvisedSupport中,后面还会用到,具体是下一篇博客。
通知器链初始完成之后,就开始生成代理对象了。
二、生成代理对象
在getObject 中我们看到,根据目标对象是否是单例提供两种生成代理对象的方式。
我们首先看单例模式的情况:getSingletonInstance();
主要看最后一行this.singletonInstance = getProxy(createAopProxy());代码。
getProxy的实现如下:
此时有一个类AopProxy,这个类就是spring中负责生产代理对象的类。准确的说这是一个接口。具体工作是由他的实现类完成的。
在Spring中还提供了一个生成这个AopProxy实现类的工厂类:AopProxyFactory 。其实这个AopProxyFactory 也是一个接口。
所以,在这个地方spring使用的时抽象工厂模式。在spring中AopProxyFactory 只有一个实现类DefaultAopProxyFactory。
AopProxy由两个直接的实现类JdkDynamicAopProxy和ObjenesisCglibAopProxy。
总结一下就是:由DefaultAopProxyFactory负责生成两个AopProxy。由JdkDynamicAopProxy和ObjenesisCglibAopProxy负责生成代理对象。
逻辑表述完毕。我们看下源码实现。
这行代码有一个参数createAopProxy()
this.singletonInstance = getProxy(createAopProxy());
我们看下这个方法createAopProxy()
这个方法定义在 父类ProxyCreatorSupport中了
我们解释一下,createAopProxy 这个方法就是创建AopProxy,刚才我们表述过,这个是由AopProxyFactory 工厂创建的。
Ok,我们需要继续看getAopProxyFactory()这个方法,获取AopProxyFactory 工厂的方法。
这个方法很简单,返回本身的aopProxyFactory对象,这个又是什么呢,我们看ProxyCreatorSupport父类的构造函数:
我们发现就是默认的DefaultAopProxyFactory 工厂类。
那么createAopProxy(this); 这个方法就是DefaultAopProxyFactory 类中的方法了。
我们看下这个方法:
在这个方法中我们看到了两个AopProxy实现类的创建过程。
我们还看这个createAopProxy(this);他传递的参数时this
他是自然ProxyCreatorSupport这个类的一个实例。
由于ProxyCreatorSupport是AdvisedSupport 子类,所以这个参数就可以理解了。为什么要传递这个AdvisedSupport 参数我们等下说明。
现在我们假设创建的类是JdkDynamicAopProxy;
这个类是用来创建代理对象的,我们看下这个方法aopProxy.getProxy(this.proxyClassLoader);
那么getProxy 就是JdkDynamicAopProxy中的方法:
这个是上一博客讲的jdk生成代理对象的方法。现在我们来看此处的三个参数:
第一个ClassLoader ,AOP使用了一个默认的ClassLoader 。事实上我们使用任何一个类都可以得到ClassLoader 。这个目标对象无关。
proxiedInterfaces 这个参数就是需要从AdvisedSupport中获取的。在这个getSingletonInstance() 方法最开始时,有一个方法 setInterfaces,这个方法在AdvisedSupport中定义,就是将接口信息保存进了AdvisedSupport中list中。这也是在createAopProxy(this);方法传递this,即传递AdvisedSupport的原因。
第三个this:此处的this 就是JdkDynamicAopProxy,因为这个类实现了InvocationHandler这个接口这就意味着 在JdkDynamicAopProxy 还有一个invoke方法。我们稍后分析这个方法,在下一篇博客中分析。以我们刚才的分析,此时生成了目标对象的代理对象。
我们会设计到三个主要的类:
ProxyFactoryBean
ProxyCreatorSupport
AdvisedSupport
从上到下时继承的关系。为便于区分我们称之为子类ProxyFactoryBean,父类ProxyCreatorSupport和祖类AdvisedSupport。
生成代理对象过程从子类ProxyFactoryBean开始的。
这个一个FactoryBean,我们会在配置文件中配置这个bean,通过这个bean获取代理对象的。因为的他名字就是代理工厂Bean。
获取代理对象是通过getObject方法,我们把对目标对象的增强都封装在了这个方法中。
@Override public Object getObject() throws BeansException { initializeAdvisorChain(); if (isSingleton()) { return getSingletonInstance(); } 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(); } }
在这个方法开始的时候,有一个方法initializeAdvisorChain,这个是用来初始化通知器链的方法。
一、初始化通知器链的过程
在初始化通知器链的过程时,spring会读取配置文件,获得通知器链的名字,然后根据名字,通过getBean方法,获得它的实例。
然后将实例保存起来,具体的保存时通过下面的这个方法:
addAdvisorOnChainCreation(advice, name); private void addAdvisorOnChainCreation(Object next, String name) { // We need to convert to an Advisor if necessary so that our source reference // matches what we find from superclass interceptors. Advisor advisor = namedBeanToAdvisor(next); if (logger.isTraceEnabled()) { logger.trace("Adding advisor with name '" + name + "'"); } addAdvisor(advisor); }
主要调用的方法就是addAdvisor(advisor);很简单。
不过这个方法是祖类AdvisedSupport中定义的。
AdvisedSupport中有一个Linkedlist属性,用于存放通知器。它是私有的。
public void addAdvisor(Advisor advisor) { int pos = this.advisors.size(); addAdvisor(pos, advisor); } @Override public void addAdvisor(int pos, Advisor advisor) throws AopConfigException { if (advisor instanceof IntroductionAdvisor) { validateIntroductionAdvisor((IntroductionAdvisor) advisor); } addAdvisorInternal(pos, advisor); } private void addAdvisorInternal(int pos, Advisor advisor) throws AopConfigException { Assert.notNull(advisor, "Advisor must not be null"); if (isFrozen()) { throw new AopConfigException("Cannot add advisor: Configuration is frozen."); } if (pos > this.advisors.size()) { throw new IllegalArgumentException( "Illegal position " + pos + " in advisor list with size " + this.advisors.size()); } this.advisors.add(pos, advisor); updateAdvisorArray(); adviceChanged(); }
此时就将通知器保存进了AdvisedSupport中,后面还会用到,具体是下一篇博客。
通知器链初始完成之后,就开始生成代理对象了。
二、生成代理对象
在getObject 中我们看到,根据目标对象是否是单例提供两种生成代理对象的方式。
我们首先看单例模式的情况:getSingletonInstance();
private synchronized Object getSingletonInstance() { if (this.singletonInstance == null) { this.targetSource = freshTargetSource(); if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) { // Rely on AOP infrastructure to tell us what interfaces to proxy. Class<?> targetClass = getTargetClass(); if (targetClass == null) { throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy"); } setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader)); } // Initialize the shared singleton instance. super.setFrozen(this.freezeProxy); this.singletonInstance = getProxy(createAopProxy()); } return this.singletonInstance; }
主要看最后一行this.singletonInstance = getProxy(createAopProxy());代码。
getProxy的实现如下:
protected Object getProxy(AopProxy aopProxy) { return aopProxy.getProxy(this.proxyClassLoader); }
此时有一个类AopProxy,这个类就是spring中负责生产代理对象的类。准确的说这是一个接口。具体工作是由他的实现类完成的。
在Spring中还提供了一个生成这个AopProxy实现类的工厂类:AopProxyFactory 。其实这个AopProxyFactory 也是一个接口。
所以,在这个地方spring使用的时抽象工厂模式。在spring中AopProxyFactory 只有一个实现类DefaultAopProxyFactory。
AopProxy由两个直接的实现类JdkDynamicAopProxy和ObjenesisCglibAopProxy。
总结一下就是:由DefaultAopProxyFactory负责生成两个AopProxy。由JdkDynamicAopProxy和ObjenesisCglibAopProxy负责生成代理对象。
逻辑表述完毕。我们看下源码实现。
这行代码有一个参数createAopProxy()
this.singletonInstance = getProxy(createAopProxy());
我们看下这个方法createAopProxy()
这个方法定义在 父类ProxyCreatorSupport中了
protected final synchronized AopProxy createAopProxy() { if (!this.active) { activate(); } return getAopProxyFactory().createAopProxy(this); }
我们解释一下,createAopProxy 这个方法就是创建AopProxy,刚才我们表述过,这个是由AopProxyFactory 工厂创建的。
Ok,我们需要继续看getAopProxyFactory()这个方法,获取AopProxyFactory 工厂的方法。
public AopProxyFactory getAopProxyFactory() { return this.aopProxyFactory; }
这个方法很简单,返回本身的aopProxyFactory对象,这个又是什么呢,我们看ProxyCreatorSupport父类的构造函数:
public ProxyCreatorSupport() { this.aopProxyFactory = new DefaultAopProxyFactory(); }
我们发现就是默认的DefaultAopProxyFactory 工厂类。
那么createAopProxy(this); 这个方法就是DefaultAopProxyFactory 类中的方法了。
我们看下这个方法:
@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实现类的创建过程。
我们还看这个createAopProxy(this);他传递的参数时this
他是自然ProxyCreatorSupport这个类的一个实例。
由于ProxyCreatorSupport是AdvisedSupport 子类,所以这个参数就可以理解了。为什么要传递这个AdvisedSupport 参数我们等下说明。
现在我们假设创建的类是JdkDynamicAopProxy;
这个类是用来创建代理对象的,我们看下这个方法aopProxy.getProxy(this.proxyClassLoader);
那么getProxy 就是JdkDynamicAopProxy中的方法:
@Override public Object getProxy(ClassLoader classLoader) { …… return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); }
这个是上一博客讲的jdk生成代理对象的方法。现在我们来看此处的三个参数:
第一个ClassLoader ,AOP使用了一个默认的ClassLoader 。事实上我们使用任何一个类都可以得到ClassLoader 。这个目标对象无关。
proxiedInterfaces 这个参数就是需要从AdvisedSupport中获取的。在这个getSingletonInstance() 方法最开始时,有一个方法 setInterfaces,这个方法在AdvisedSupport中定义,就是将接口信息保存进了AdvisedSupport中list中。这也是在createAopProxy(this);方法传递this,即传递AdvisedSupport的原因。
第三个this:此处的this 就是JdkDynamicAopProxy,因为这个类实现了InvocationHandler这个接口这就意味着 在JdkDynamicAopProxy 还有一个invoke方法。我们稍后分析这个方法,在下一篇博客中分析。以我们刚才的分析,此时生成了目标对象的代理对象。
相关文章推荐
- 一个jar包里的网站
- 一个jar包里的网站之文件上传
- 一个jar包里的网站之返回对媒体类型
- Spring和ThreadLocal
- Spring Boot 开发微服务
- JDK动态代理VS CgLib
- Spring AOP动态代理-切面
- Spring整合Quartz(JobDetailBean方式)
- Spring整合Quartz(JobDetailBean方式)
- yui3的AOP(面向切面编程)和OOP(面向对象编程)
- PHP strtotime函数用法、实现原理和源码分析
- 动态代理的5模式使用示例和Mixin模式
- jQuery 源码分析笔记(3) Deferred机制
- JavaScript AOP编程实例
- 使用AOP改善javascript代码