我们都知道AOP底层是动态代理,java中有两种动态代理,一种是java自带的基于JDK的动态代理,一种是CGlib的动态代理。
两者最大的区别就是基于JDK动态代理的被代理对象需要有接口,而基于CGlib的动态代理并不需要被代理类有接口。
1.Spring
在Spring中的动态代理具体使用哪种就分情况了
如果代理对象有接口,就用 JDK 动态代理,否则就是 Cglib 动态代理。
如果代理对象没有接口,那么就直接是 Cglib 动态代理。
官网贴图
而在SpringBoot中,在2.0版本之前关于AOP代码是:
@Configuration
@ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class })
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = false)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false",
matchIfMissing = true)
public static class JdkDynamicAutoProxyConfiguration {
}
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
matchIfMissing = false)
public static class CglibAutoProxyConfiguration {
}
}
可以看到,这个自动化配置主要就是对spring.aop.proxy-target-class进行讨论
图中的几个重要属性的意思
prefix 前缀
name 配置文件的名字 和prefix组成key
havingValue 期待匹配的值,如果实际值和havingVlue的值相同,则这个配置就会生效
matchIfMissing 如果开发者没有在properties中配置中进行设置,那这个配置是否生效
很显然 在SpringBoot2.0之前 默认使用的jdk动态代理
而Spring2.0以后呢
@Configuration
@ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class,
AnnotatedElement.class })
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = false)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false", matchIfMissing = false)
public static class JdkDynamicAutoProxyConfiguration {
}
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true)
public static class CglibAutoProxyConfiguration {
}
}
主要看matchIfMissing 发现 默认的使用的是CGlib动态代理。
如果想设置成JDK动态代理,只需要在配置文件中添加 spring.aop.proxy-target-class=false