1. 什么是spring的Aop
在进行源码解读之前,大家需要对Spring的Aop有基础的认识和理解,参考文章:Spring之AOP理解与应用-CSDN博客
2. 源码解读
接下来,我们对AOP的源码进行一个解读。
2.1 动态代理
如果你已经对spring的Aop已经有了基础的认识,那么你一定知道它的底层是用动态代理实现的。作为一个java程序员,我们都知道,实现动态代理的方式有两种,一种是jdk自生提供了一种创建代理对象的动态代理机制,其特点是代理类必须实现了接口;另一种是cglib技术。那么Spring中到底用了哪一种呢?
其实spring中这两种代理技术都用到了,它把这两种动态代理的方式进行了封装,封装成的类叫做ProxyFactory,表示是创建代理对象的一个工厂。通过ProxyFactory,我们可以不用关心到底是用cglib还是jdk动态代理了,ProxyFactory会帮我们去判断,如果要代理的类实现了接口,那么ProxyFactory底层就会用jdk动态代理,如果没有实现接口,就会用cglib技术。
以下源码则是spring在生成AOP代理对象之前需要决定到底是使用JDK动态代理还是CGLIB技术:
AopProxyFactory的子类DefaultAopProxyFactory中的createAopProxy方法@Overridepublic AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {// 如果ProxyFactory的isOptimize为true,Spring认为cglib比jdk动态代理要快// 或者isProxyTargetClass为true,// 或者被代理对象没有实现接口,// 或者只实现了SpringProxy这个接口// 那么则利用Cglib进行动态代理,但如果被代理类是接口,或者被代理类已经是进行过JDK动态代理而生成的代理类了则只能进行JDK动态代理// 其他情况都会进行JDK动态代理,比如被代理类实现了除SpringProxy接口之外的其他接口// 是不是在GraalVM虚拟机上运行if (!NativeDetector.inNativeImage() &&(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.");}// targetClass是接口,直接使用Jdk动态代理if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {return new JdkDynamicAopProxy(config);}// 使用Cglibreturn new ObjenesisCglibAopProxy(config);}else {// 使用Jdk动态代理return new JdkDynamicAopProxy(config);}}