基于最新Spring 5.x,详细介绍了Spring 事务源码,包括< tx:annotation-driven/>标签源码解析。
此前我们已经学习了Spring的<tx:advice/>事务标签源码解析:Spring 事务源码(1)—<tx:advice/>事务标签源码解析。现在我们来学习<tx:annotation-driven/>
事务标签的解析源码。
<tx:annotation-driven/>
标签用于开启注解事务支持,也就是说如果配置了该标签,那么可以使用基于注解的声明式事务!
<tx:annotation-driven/>
标签由org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser
这个解析器来单独解析,该解析器的uml类图如下,比较简单:
同样,我们主要看它的parse方法!
Spring 事务源码 系列文章
Spring 事务源码(1)—<tx:advice/>事务标签源码解析
Spring 事务源码(2)—<tx:annotation-driven/>事务标签源码解析
Spring 事务源码(3)—@EnableTransactionManagement事务注解源码解析
Spring 事务源码(4)—BeanFactoryTransactionAttributeSourceAdvisor注解事务通知器源码解析
Spring 事务源码(5)—TransactionInterceptor事务拦截器与事务的AOP增强实现
Spring 事务源码(6)—createTransactionIfNecessary处理事务属性并尝试创建事务【两万字】
Spring 事务源码(7)—事务的completeTransactionAfterThrowing回滚、commitTransactionAfterReturning提交以及事务源码总结【一万字】
文章目录
1 parse解析< tx:annotation-driven/>标签
解析<tx:annotation-driven/>
标签。将在必要时调用AopNamespaceUtils#registerAutoProxyCreatorIfNecessary
方法,尝试向容器中注册一个InfrastructureAdvisorAutoProxyCreator
类型的bean定义。
/**
* AnnotationDrivenBeanDefinitionParser的方法
* <p>
* 解析<tx:annotation-driven/>标签
* 将在必要时调用AopNamespaceUtils#registerAutoProxyCreatorIfNecessary方法
* 尝试向容器中注册一个InfrastructureAdvisorAutoProxyCreator类型的AutoProxyCreator。
*/
@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {
/*
* 注册事务事件监听器工厂TransactionalEventListenerFactory的bean定义
* 用于解析@TransactionalEventListener注解方法为一个ApplicationListenerMethodTransactionalAdapter监听器
*/
registerTransactionalEventListenerFactory(parserContext);
//获取<tx:annotation-driven/>标签的mode属性
//该属性用于指示应该采用Spring AOP来对异步方法进行动态代理,还是采用AspectJ来进行静态织入
//默认为proxy,即Spring AOP代理,如果设置为aspectj,那么还需要spring-aspects.jar(其内部包含了aspectjweaver依赖)。
String mode = element.getAttribute("mode");
//aspectj的mode处理,一般不需要考虑
if ("aspectj".equals(mode)) {
// mode="aspectj"
registerTransactionAspect(element, parserContext);
if (ClassUtils.isPresent("javax.transaction.Transactional", getClass().getClassLoader())) {
registerJtaTransactionAspect(element, parserContext);
}
} else {
// mode="proxy"
//正常情况下的逻辑
//尝试注册一个InfrastructureAdvisorAutoProxyCreator类型的自动代理创建者
//并且配置AOP事务相关的一些基础bean定义,比如事务通知器、事务拦截器、事务属性源
AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
}
return null;
}
1.1 registerTransactionalEventListenerFactory注册事务事件监听器工厂
注册TransactionalEventListenerFactory
的bean定义,名为“org.springframework.transaction.config.internalTransactionalEventListenerFactory”
。该工厂可以将@TransactionalEventListener注解方法
解析为一个ApplicationListenerMethodTransactionalAdapter类型的事件监听器,用于支持事务事件的监听。
/**
1. AnnotationDrivenBeanDefinitionParser的方法
2. <p>
3. 注册TransactionalEventListenerFactory的bean定义
*/
private void registerTransactionalEventListenerFactory(ParserContext parserContext) {
//创建bean定义
RootBeanDefinition def = new RootBeanDefinition();
//设置为TransactionalEventListenerFactory类型
def.setBeanClass(TransactionalEventListenerFactory.class);
//注册bean定义到beanFactory中,beanName为"org.springframework.transaction.config.internalTransactionalEventListenerFactory"
parserContext.registerBeanComponent(new BeanComponentDefinition(def,
TransactionManagementConfigUtils.TRANSACTIONAL_EVENT_LISTENER_FACTORY_BEAN_NAME));
}
1.2 configureAutoProxyCreator配置自动代理创建者
configureAutoProxyCreator方法是内部类AopAutoProxyConfigurer的方法,该方法有两个目的:
- 尝试注册一个
InfrastructureAdvisorAutoProxyCreator
类型的自动代理创建者,用于创建代理对象。 - 配置AOP事务相关的一些基础bean定义,比如配置
BeanFactoryTransactionAttributeSourceAdvisor事务通知器、AnnotationTransactionAttributeSource注解事务属性源、TransactionInterceptor事务拦截器
等。
事务通知器的beanName为org.springframework.transaction.config.internalTransactionAdvisor
,并且全局只有一个,只有当容器中不存在该bean时才会继续解析当前<tx:annotation-driven/>
标签。因此,即使配置文件中存在多个<tx:annotation-driven/>
标签,仍然只会有一个标签的配置生效。
/**
* AnnotationDrivenBeanDefinitionParser的内部类
* <p>
* 尝试注册一个InfrastructureAdvisorAutoProxyCreator类型的自动代理创建者
* 并且配置AOP事务相关的一些基础bean定义,比如事务通知器、事务拦截器、事务属性源
*/
private static class AopAutoProxyConfigurer {
/**
* 配置自动代理创建者
*/
public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
/*
* 如有必要,注册一个InfrastructureAdvisorAutoProxyCreator类型的AutoProxyCreator
* 并且配置proxy-target-class与expose-proxy属性
*/
AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
//获取事务通知器的banName,默认就是"org.springframework.transaction.config.internalTransactionAdvisor"
String txAdvisorBeanName = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME;
/*
* 如果目前不包含该名称的bean,那么将会注册一个BeanFactoryTransactionAttributeSourceAdvisor类型的注解专用事务通知器
* 并且配置TransactionInterceptor事务拦截器以及AnnotationTransactionAttributeSource注解事务属性源的bean定义
*
* 这里能够看出,即使可能存在多个<tx:annotation-driven/>标签,仍然只会有一个标签的配置生效
*/
if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) {
Object eleSource = parserContext.extractSource(element);
// 创建一个bean定义,class为"org.springframework.transaction.annotation.AnnotationTransactionAttributeSource"
//就是一个适用于注解的事务属性源
RootBeanDefinition sourceDef = new RootBeanDefinition(
"org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");
sourceDef.setSource(eleSource);
sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
//注册事物属性源到容器中并且返回beanName
String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
//创建TransactionInterceptor事务拦截器的bean定义
RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);
interceptorDef.setSource(eleSource);
interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
/*
* 注册事务管理器到事务拦截器中
* 实际上就是设置TransactionInterceptor的transactionManagerBeanName属性指向一个事务管理器的bean
*/
registerTransactionManager(element, interceptorDef);
interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
//注册拦截器到容器中并且返回beanName
String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);
// Create the TransactionAttributeSourceAdvisor definition.
/*
* 创建一个TransactionAttributeSourceAdvisor的bean定义
* 实际类型为BeanFactoryTransactionAttributeSourceAdvisor,就是一个事务通知器
*/
RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
advisorDef.setSource(eleSource);
advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
//设置transactionAttributeSource属性,就是AnnotationTransactionAttributeSource事务属性源
advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
//设置adviceBeanName属性,就是TransactionInterceptor事务拦截器
advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);
//设置事务通知器的order属性
if (element.hasAttribute("order")) {
advisorDef.getPropertyValues().add("order", element.getAttribute("order"));
}
//将当前事务通知器的bean定义注册到容器中,name为"org.springframework.transaction.config.internalTransactionAdvisor"
parserContext.getRegistry().registerBeanDefinition(txAdvisorBeanName, advisorDef);
//发布事件
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);
compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName));
compositeDef.addNestedComponent(new BeanComponentDefinition(interceptorDef, interceptorName));
compositeDef.addNestedComponent(new BeanComponentDefinition(advisorDef, txAdvisorBeanName));
parserContext.registerComponent(compositeDef);
}
}
}
/**
1. AnnotationDrivenBeanDefinitionParser的方法
2. <p>
3. 注册事务管理器到事务拦截器中
4. 5. @param element <tx:annotation-driven/>标签元素
6. @param def 事务拦截器的bean定义
*/
private static void registerTransactionManager(Element element, BeanDefinition def) {
//通过TxNamespaceHandler.getTransactionManagerName来获取事务管理器的beanName
//将会解析<tx:annotation-driven/>标签的transaction-manager属性,默认值同样是transactionManager
def.getPropertyValues().add("transactionManagerBeanName",
TxNamespaceHandler.getTransactionManagerName(element));
}
1.2.1 registerAutoProxyCreatorIfNecessary注册自动代理创建者
如有必要,注册一个InfrastructureAdvisorAutoProxyCreator
类型的AutoProxyCreator
。该方法的源码与我们在此前的Spring AOP源码(1)—<aop:config/>AOP配置标签解析【一万字】的文章中讲过的registerAspectJAutoProxyCreatorIfNecessary方法基本一致。只不过AutoProxyCreator的类型变成了InfrastructureAdvisorAutoProxyCreator。
该方法分为三步,我们在此前已经讲过具体的源码了,在此不再赘述:
- 调用AopConfigUtils.registerAutoProxyCreatorIfNecessary,尝试注册一个名为"org.springframework.aop.config.internalAutoProxyCreator",类型为InfrastructureAdvisorAutoProxyCreator的自动代理创建者的bean定义。
- 调用useClassProxyingIfNecessary,解析proxy-target-class与expose-proxy属性。
- 调用registerComponentIfNecessary注册组件,这里的注册是指存放到外层方法新建的CompositeComponentDefinition对象的内部集合中或者广播事件,而不是注册到注册表中。
/**
* AopNamespaceUtils的方法
* <p>
* 如有必要,注册一个InfrastructureAdvisorAutoProxyCreator类型的AutoProxyCreator
* <p>
* 该方法的源码与我们在此前的<aop:config/>标签解析部分讲过的registerAspectJAutoProxyCreatorIfNecessary方法基本一致
* 只不过AutoProxyCreator的类型变成了InfrastructureAdvisorAutoProxyCreator
*/
public static void registerAutoProxyCreatorIfNecessary(
ParserContext parserContext, Element sourceElement) {
/*
* 1 尝试注册或者升级一个名为"org.springframework.aop.config.internalAutoProxyCreator"
* 类型为InfrastructureAdvisorAutoProxyCreator的自动代理创建者的bean定义
*/
BeanDefinition beanDefinition = AopConfigUtils.registerAutoProxyCreatorIfNecessary(
parserContext.getRegistry(), parserContext.extractSource(sourceElement));
/*
* 2 解析proxy-target-class与expose-proxy属性
* proxy-target-class用于设置代理模式,默认是优先JDK动态代理,其次CGLIB代理,可以指定为CGLIB代理
* expose-proxy用于暴露代理对象,主要用来解决同一个目标类的方法互相调用时代理不生效的问题
*/
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
/*
* 3 注册组件,这里的注册是指存放到外层方法新建的CompositeComponentDefinition对象的内部集合中或者广播事件,而不是注册到注册表中
*/
registerComponentIfNecessary(beanDefinition, parserContext);
}
/**
1. AopConfigUtils的方法
2. <p>
3. 注册/升级自动代理创建者为InfrastructureAdvisorAutoProxyCreator类型
*/
@Nullable
public static BeanDefinition registerAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
/*
* 注册/升级自动代理创建者为InfrastructureAdvisorAutoProxyCreator类型
* 这个方法我们在此前的<aop:config/>标签解析部分也讲过了
*/
return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
}
2 小结
<tx:annotation-driven/>
标签用于开启注解事务支持,也就是说如果配置了该标签,那么可以使用基于注解的声明式事务!
从源码中能看出,该标签会:
- 尝试向容器注册名为org.springframework.transaction.config.internalTransactionalEventListenerFactory的
TransactionalEventListenerFactory类型的事务事件监听器工厂
的bean定义,该bean用于解析@TransactionalEventListener注解方法为一个ApplicationListenerMethodTransactionalAdapter监听器。 - 还会尝试注册一个名为org.springframework.aop.config.internalAutoProxyCreator的
InfrastructureAdvisorAutoProxyCreator类型的自动代理创建者
的bean定义,该bean用于创建代理对象。但是该beanName的bean定义在容器中全局只会注册一个,并且有优先级,这一点我们在此前Spring AOP源码(1)—<aop:config/>AOP配置标签解析【一万字】的文章中就讲过了。 - 还会尝试
配置AOP事务相关的一些基础bean定义
,比如配置BeanFactoryTransactionAttributeSourceAdvisor事务通知器、AnnotationTransactionAttributeSource注解事务属性源(专门用于解析事务注解)
、TransactionInterceptor事务拦截器等。
总体来说,源码比较简单!当然前提是在我们理解了Spring AOP的源码之后才能得出这样的结论。
相关文章:
https://spring.io/
Spring Framework 5.x 学习
Spring Framework 5.x 源码
如有需要交流,或者文章有误,请直接留言。另外希望点赞、收藏、关注,我将不间断更新各种Java学习博客!