前言
在上一篇文章中,我们讲解了Spring中那些注解可能会产生AOP动态代理,我们通过源码发现,完成AOP相关操作都和ProxyFactory这个类有密切关系,这一篇我们将围绕这个类继续解析
演示
作用
ProxyFactory采用策略模式生成动态代理对象,具体生成cglib动态代理还是jdk动态代理,是根据我们具体设置的内容所决定的,我们分别演示一下生成cglib动态代理和jdk动态代理两种情况。具体细节可以详细阅读DefaultAopProxyFactory的createAopProxy方法
生成cglib动态代理
package com.test.aop.test;
public class CglibTarget {
public void doObject() {
System.out.println("CglibTarget doObject");
}
}
package com.test.aop.test;
import org.springframework.aop.framework.ProxyFactory;
public class CglibProxy {
public static void main(String[] args) {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(new CglibTarget());
CglibTarget proxy = (CglibTarget) proxyFactory.getProxy();
proxy.doObject();
}
}
我们可以发现最终是以cglib动态代理方式生成代理对象
生成jdk动态代理
package com.test.aop.test;
public interface JdkTarget {
void doObject();
}
package com.test.aop.test;
public class JdkTargetImpl implements JdkTarget {
@Override
public void doObject() {
System.out.println("JdkTargetImpl doObject");
}
}
package com.test.aop.test;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.target.SingletonTargetSource;
public class JdkProxy {
public static void main(String[] args) {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setInterfaces(JdkTarget.class);
proxyFactory.setTargetSource(new SingletonTargetSource(new JdkTargetImpl()));
JdkTarget proxy = (JdkTarget) proxyFactory.getProxy();
proxy.doObject();
}
}
我们可以发现最终是以jdk动态代理方式生成代理对象
ProxyFactory源码解析
我们先观察一下ProxyFactory这个类的继承关系
我们以proxyFactory.getProxy()方法为切入口,进行源码解析
对上述流程进行梳理,见下图
我们分别查看两种方式的代理过程
jdk动态代理过程(JdkDynamicAopProxy)
jdk动态代理的过程比较简单主要就是利用Proxy.newProxyInstance方法创建代理对象
cglib动态代理过程(CglibAopProxy)
cglib动态代理主要利用我们自定义的ProxyFactory对象,然后根据设置的参数构建Enhancer对象,然后创建代理对象。我们需要注意的是代理对象一共有七个拦截器,spring会根据我们调用的方法,指定拦截器。比如我们调用equal方法就会经过EqualsInterceptor拦,调用hashCode方法就会调用HashCodeInterceptor,我们主要需要关注的就是DynamicAdvisedInterceptor,一般增强的方法都会经过这个拦截器。具体进入那个拦截器可以查看CglibAopProxy类的accept方法
ProxyFactory的重要属性Advisor
我们在前文中说到@EnableTransactionManagement,@EnableAspectJAutoProxy完成AOP动态代理都是依靠AbstractAutoProxyCreator的postProcessAfterInitialization方法中完成的,其中最主要的方法是wrapIfNecessary,我们查看相关源码
通过源码我们知道只有找到了增强点,spring才会进行动态代理
我们在上文中提到了@EnableTransactionManagement,@EnableAspectJAutoProxy两个注解的渊源,然后得出结论:如果同时存在,最终只能存在一个优先级更高的BeanPostProcessor(bpp)
那么@EnableAspectJAutoProxy这个注解注入了一个优先级更高的bpp,有什么扩展点呢?我们以上图中getAdvicesAndAdvisorsForBean方法为切入口进行分析
findCandidateAdvisors在两个注解注入的bpp的共同父类有一个默认实现,但是@EnableAspectJAutoProxy这个注解注入的bpp(AnnotationAwareAspectJAutoProxyCreator)重写了findCandidateAdvisors方法,重写的方法会对默认方法进行扩展
文章来源:https://www.toymoban.com/news/detail-835040.html
总结
ProxyFactory这个类在Spring完成AOP动态代理的过程中起到了重要的作用,具体如下所述文章来源地址https://www.toymoban.com/news/detail-835040.html
- 决定Spring进行aop动态代理的方式(jdk动态代理或者cglib动态代理)
- 可以设置监听器,监听动态代理对象
- 可以决定是否提前暴露代理对象(属性exposeProxy=true则会提前暴露)
- 可以通过查找增强点,决定是否需要进行动态代理
到了这里,关于Spring之AOP源码解析(中)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!