深入理解Spring AOP之二代理对象生成

调用方法步骤可以如下所示:新建一个target,target使我们需要操作的目标定义一个代理工厂,可以是ProxyFactory或者ProxyFactorybean两种方法,Bean顾名思义,采用的Spring中的IOC机制,而ProxyFactory方法则可以直接得到加入通知得到代理实例,通过getproxy()方法先看ProxyFactory是如何得到代理类的找到proxyFactory中的getProxy()方法;public Object getProxy() {return createAopProxy().getProxy();}AopProxy createAopProxy() {if (!this.active) {activate();}return getAopProxyFactory().createAopProxy(this);}

实现它获得一个用来产生代理的实例, createAopProxy() 方法返回 AopProxy, 然后再调用 getProxy() 方法产生具体的代理对象,这里下面再细讲,因为在ProxyFactoryBean中也用到了一样的父类。

得到了一个AopProxy之后,再利用AopProxy的方法,根据条件获得一个用来产生代理的实例,要么是JDK动态代理生成,要么是Cglib代理生成。ProxyFactoryBean是如何获得代理类的

找到ProxyFactoryBean方法,ProxyFactoryBean是在Spring IoC环境中,创建AOP应用的最底层方法,从中,可以看到一条实现AOP的基本线索。借助如上类图,看看AOP代理类是如何产生的(回顾下动态代理中的代理类生成方法)

先看看ProxyFactoryBean中的getObject方法

为什么要先看getObject方法呢:如果容器中的某个对象持有某个FactoryBean的引用,它取得的不是FactoryBean本身,而是FactoryBean的getObject()方法所返回的对象。所以,如果容器中某个对象依赖于ProxyFactoryBean,那么它将会使用到ProxyFactoryBean的getObject()方法所返回的代理对象 @Overridepublic 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}}

继续跟踪getSingletonInstance()方法,这个地方可以看出点东西private synchronized Object getSingletonInstance() {if (this.singletonInstance == null) {this.targetSource = freshTargetSource();//返回被 代 理的 目标对象if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {//从targetSource中获取目标对象的ClassClass<?> 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来生成需要的Proxythis.singletonInstance = getProxy(createAopProxy());}return this.singletonInstance;}

这里看看setFrozen()和createAopProxy()方法,调用的是proxyFactoryBean上一层接口ProxyCreatorSupport中的方法(看类图),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()方法,终于真相大白,如下@Overridepublic 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()方法@Overridepublic 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 AOP之二代理对象生成

相关文章:

你感兴趣的文章:

标签云: