目录
Spring
中 Aop
的实现
- 如果代理对象有接口,就用
JDK
动态代理。JDK
动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法时,会先调用实现了InvokeHandler
接口的invoke()
方法,来实现业务增强 - 如果代理对象没有接口,那么就直接使用
Cglib
动态代理。Cglib
动态代理是利用asm
开源包,对代理对象类的class
文件加载进来,通过修改其字节码生成子类来处理
来自 Spring
官方文档的说辞
可以看到,即使在最新版的 Spring
中,依然是如上策略不变。即能用 JDK
做动态代理就用 JDK
,不能用 JDK
做动态代理就用 Cglib
,即首选 JDK
做动态代理
Spring
中代理对象产生的源码
DefaultAopProxyFactory
类的 createAopProxy()
方法,具体源码可以参考
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
// 获得被代理对象的类型,以确定代理的方式
Class<?> targetClass = config.getTargetClass();
// 如果对象类型是接口,或者是JAVA的动态代理类,那么就调用JDK的动态代理方法生成代理对象
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
// 否则使用CGLIB生成代理对象
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
SpringBoot
中 Aop
的实现
SpringBoot
和 Spring
一脉相承,那么在动态代理这个问题上是否也是相同的策略呢?
抱歉,这个还真不一样,SpringBoot
中对这个问题的处理,以 SpringBoot 2.0
为节点,前后不一样
SpringBoot 2.0
之前
关于 Aop
的自动化配置代码是这样的(SpringBoot 1.5.22.RELEASE
)
@Configuration
@ConditionalOnClass({
EnableAspectJAutoProxy.class,