好了,开始今天的正文。大家都知道AOP的底层是动态代理,而在Java中实现动态代理有两种方式:基于JDK的动态代理和基于Cglib的动态代理。两者最大的区别是基于JDK的动态代理需要代理。Interface,而基于Cglib的动态代理不需要代理对象有接口。那么小伙伴们不禁要问,Spring中的AOP是如何实现的呢?是基于JDK的动态代理还是基于Cglib的动态代理?1、Spring先说结论,用Spring中的哪个动态代理,看情况:如果代理对象有接口,就用JDK动态代理,否则就是Cglib动态代理。如果代理对象没有接口,则直接是一个Cglib动态代理。我们来看看官方文档中的这段说法:可以看到,即使在最新版本的Spring中,上述策略也没有改变。即能用JDK做动态代理就用JDK,不能用JDK做动态代理就用Cglib,也就是首选JDK做动态代理。2、SpringBootSpringBoot和Spring是一脉相承的,那么在动态代理的问题上是不是同一个策略呢?对不起,这个真的很不一样。SpringBoot对这个问题的处理,以SpringBoot2.0为节点,前后不一样。在SpringBoot2.0之前Aop的自动配置代码是这样的(SpringBoot1.5.22.RELEASE):@Configuration@ConditionalOnClass({EnableAspectJAutoProxy.class,Aspect.class,Advice.class})@ConditionalOnProperty(prefix="spring.aop",name="auto",havingValue="true",matchIfMissing=true)publicclassAopAutoConfiguration{@Configuration@EnableAspectJAutoProxy(proxyTargetClass=false)@ConditionalOnProperty(prefix="spring.aop",name="代理目标-class",havingValue="false",matchIfMissing=true)publicstaticclassJdkDynamicAutoProxyConfiguration{}@Configuration@EnableAspectJAutoProxy(proxyTargetClass=true)@ConditionalOnProperty(prefix="spring.aop",name="proxy-target-class",havingValue="true",matchIfMissing=false)publicstaticclassCglibAutoProxyConfiguration{}}可以看到,这个自动配置主要是在application.properties配置文件中讨论spring.aop.proxy-target-class属性的值。具体起作用的是@ConditionalOnProperty注释。关于这个注解中的几个属性,宋大哥也会稍微说一下:prefix:配置文件的前缀。name:配置文件的名称,与前缀一起构成配置键。having:预期的配置值。如果实际配置与having值相同则配置生效,否则不生效。matchIfMissing:如果开发者没有在application.properties中配置,这个配置类是否生效。根据上面的介绍,我们不难看出,如果开发者将spring.aop.proxy-target-class设置为false,就会使用JDK代理。如果开发人员将spring.aop.proxy-target-class设置为true,则使用Cglib代理。如果开发者一开始就没有配置spring.aop.proxy-target-class属性,则使用JDK代理。在SpringBoot2.0之前就是这样。我们看一下SpringBoot2.0(含)(SpringBoot2.0.0.RELEASE)之后的情况:="spring.aop",name="auto",havingValue="true",matchIfMissing=true)publicclassAopAutoConfiguration{@Configuration@EnableAspectJAutoProxy(proxyTargetClass=false)@ConditionalOnProperty(prefix="spring.aop",name="proxy-target-class",havingValue="false",matchIfMissing=false)publicstaticclassJdkDynamicAutoProxyConfiguration{}@Configuration@EnableAspectJAutoProxy(proxyTargetClass=true)@ConditionalOnProperty(prefix="spring.aop",name="代理目标-class",havingValue="true",matchIfMissing=true)publicstaticclassCglibAutoProxyConfiguration{}}可以看到大部分的配置都是一样的,但是有一点不同,就是matchIfMissing属性的取值。可以看出,从SpringBoot2.0开始,如果用户什么都不配置,默认使用Cglib代理。3.实践最后,我们写一个简单的例子来验证我们的想法。首先创建一个SpringBoot项目(本例使用最新版本的SpringBoot,即默认使用Cglib代理),添加三个依赖即可,如下:
