springboot声明式事务是通过动态代理实现的,本文通过@EnableTransactionManagement做为入口,跟踪spring代理的开启过程;
开启动态代理的功能就是引入动态代理创建器的bean定义(@EnableTransactionManagement引入InfrastructureAdvisorAutoProxyCreator)。动态代理创建器负责生成代理对象的动态代理,增强代理对象;
spring声明式事务使用动态代理实现,实现有三种方式:
使用@Import引入TransactionManagementConfigurationSelector;
默认的代理模式为PROXY,TransactionManagementConfigurationSelector的selectImports方法引入AutoProxyRegistrar和ProxyTransactionManagementConfiguration。AutoProxyRegistrar负责生成类的动态代理,其它通过动态代理实现有注解同样会引入AutoProxyRegistrar。比如@EnableCaching。ProxyTransactionManagementConfiguration为动态代理事务相关的配置;
protected String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) {
//**引入AutoProxyRegistrar和ProxyTransactionManagementConfiguration
case PROXY:
return new String[] {AutoProxyRegistrar.class.getName(),
ProxyTransactionManagementConfiguration.class.getName()};
case ASPECTJ:
return new String[] {determineTransactionAspectClass()};
default:
return null;
}
}
负责注册动态代理相关的bean定义(InfrastructureAdvisorAutoProxyCreator)。如果启用了CGLIB(proxyTargetClass=true)代理,在代理bean定义中添加属性proxyTargetClass=true;
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
boolean candidateFound = false;
//**获取@EnableTransactionManagement注册所在类的所有注解(一般都是项目的启动类SpringdemoApplication)
Set<String> annTypes = importingClassMetadata.getAnnotationTypes();
for (String annType : annTypes) {
AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annType);
if (candidate == null) {
continue;
}
Object mode = candidate.get("mode");
Object proxyTargetClass = candidate.get("proxyTargetClass");
//**获取需启用动态代理的注解
if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() &&
Boolean.class == proxyTargetClass.getClass()) {
candidateFound = true;
//**注册动态代理的bean定义(InfrastructureAdvisorAutoProxyCreator)
if (mode == AdviceMode.PROXY) {
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
//**如果启用了CGLIB(proxyTargetClass=true),在代理bean定义中添加属性(definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE);)
if ((Boolean) proxyTargetClass) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
return;
}
}
}
}
...
}
注册动态代理的bean定义InfrastructureAdvisorAutoProxyCreator。InfrastructureAdvisorAutoProxyCreator是基础设施自动代理创建器,只考虑基础设施(role=BeanDefinition.ROLE_INFRASTRUCTURE)的Advisor(Advisor:顾问,动态代理额外执行逻辑的抽象),不考虑自定义的Advisor;
@Nullable
public static BeanDefinition registerAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
//**注册动态代理的bean定义InfrastructureAdvisorAutoProxyCreator
return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
}
//*获取动态代理的bean定义(名称为org.springframework.aop.config.internalAutoProxyCreator)
//**如果当前的动态代理的bean定义不是InfrastructureAdvisorAutoProxyCreator,则根据优先级设置bean定义;
//**InfrastructureAdvisorAutoProxyCreator优先级最低,并且没有提供修改优先级的方法;
@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(
Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
}
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
//**动态代理bean的优先顺序,InfrastructureAdvisorAutoProxyCreator优先级最低
static {
APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class);
APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class);
APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class);
}
实际上项目中通常是使用AnnotationAwareAspectJAutoProxyCreator创建cglib动态代理。因为spring有配置类AopAutoConfiguration,使用@EnableAspectJAutoProxy引入AnnotationAwareAspectJAutoProxyCreator,并默认proxyTargetClass=true;
@AutoConfiguration
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(Advice.class)
static class AspectJAutoProxyingConfiguration {
@Configuration(proxyBeanMethods = false)
@EnableAspectJAutoProxy(proxyTargetClass = false)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false")
static class JdkDynamicAutoProxyConfiguration {
}
@Configuration(proxyBeanMethods = false)
@EnableAspectJAutoProxy(proxyTargetClass = true)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
matchIfMissing = true)
static class CglibAutoProxyConfiguration {
}
}
}
如果在声明式事务中想使用InfrastructureAdvisorAutoProxyCreator创建jdk动态代理,需加入以下配置;
spring.aop.auto=false
spring.aop.proxy-target-class=false