含义
proxy-target-class属性值决定是基于接口的还是基于类的代理被创建。
- true,则是基于类的代理将起作用(需要cglib库),
- false或者省略这个属性,则标准的JDK 基于接口的代理将起作用。
但是,即使设置为false,如果目标类没有生命接口,则Spring将自动使用CGLib动态代理。
用大白话来说,就是当要使用实现了某个接口的类,让Spring来生成bean时,会使用aop动态代理技术,生成代理类。此时,程序需要知道,采用哪一种代理技术,是CGLIB代理还是JDK代理。
JDK动态代理通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口。JDK动态代理的核心是InvocationHandler接口和Proxy类。
如果目标类没有实现接口,那么Spring AOP会选择使用CGLIB来动态代理目标类。
CGLIB(Code Generation Library),是一个代码生成的类库,是利用asm开源包,可以在运行时动态的生成某个类的子类。注意,CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。
示例
在TransactionAutoConfiguration
中,有如下代码:
@Configuration(proxyBeanMethods = false)
@ConditionalOnBean(TransactionManager.class)
@ConditionalOnMissingBean(AbstractTransactionManagementConfiguration.class)
public static class EnableTransactionManagementConfiguration {
@Configuration(proxyBeanMethods = false)
@EnableTransactionManagement(proxyTargetClass = false)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false")
public static class JdkDynamicAutoProxyConfiguration {
}
@Configuration(proxyBeanMethods = false)
@EnableTransactionManagement(proxyTargetClass = true)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
matchIfMissing = true)
public static class CglibAutoProxyConfiguration {
}
}
可以看到:
- proxy-target-class为false,那么启用JdkDynamicAutoProxyConfiguration
- proxy-target-class为true,那么启用CglibAutoProxyConfiguration