在前几篇中,介绍了Spring事务中核心的原理,如事务AOP代理TransactionProxyFactoryBean及事务管理器PlatformmTransactionManager,而最终以@Transactional注解这种非侵入式甚至近乎无感知的方式运行在我们的大大小小的项目中,只需要在配置文件中加上简单的配置,因此也就称为声明式事务:事务与业务解耦。
在spring配置文件中加上事务注解驱动,以及事务管理器
1 | <!-- 事务注解驱动 --> |
此时,在需要事务的方法上加上@Transactional即可(前提是类被spring容器管理)。要分析其运行的原理,得从事务注解驱动的配置开始。根据Spring解析xml Namespace的规则,直接查找TxNamespaceHandler,对annotation-driven的解析由AnnotationDrivenBeanDefinitionParser执行。
1 | public BeanDefinition parse(Element element, ParserContext parserContext) { |
默认情况下,不用配置mode,即由其内部静态类AopAutoProxyConfigurer完成配置
1 | public static void configureAutoProxyCreator(Element element, ParserContext parserContext) { |
主要配置的有三部分:
- 事务属性源TransactionAttributeSource
- 事务拦截器TransactionInterceptor
- 事务切面TransactionAttributeSourceAdvisor
事务属性源
这里配置的事务属性源是AnnotationTransactionAttributeSource,支持根据类和方法获取事务属性。
1 |
|
统一调用determineTransactionAttribute方法
1 | protected TransactionAttribute determineTransactionAttribute(AnnotatedElement ae) { |
在AnnotationTransactionAttributeSource的构造方法中,初始化了注解解析器
1 | public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) { |
SpringTransactionAnnotationParser中判断类和方法上是否有@Transactional,然后解析注解的属性
1 | public TransactionAttribute parseTransactionAnnotation(AnnotatedElement ae) { |
创建事务属性对象RuleBasedTransactionAttribute,获取事务属性配置
1 | protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) { |
@Transactional的value值定义的是由哪个事务管理器管理,如果没有配置rollbackFor和noRollbackFor属性,由RuleBasedTransactionAttribute的父类DefaultTransactionAttribute默认定义异常回滚规则:遇到运行时异常和Error回滚事务。
1 | public boolean rollbackOn(Throwable ex) { |
至此,事务属性的解析很清晰了,那么又是在何处调用事务属性源的findTransactionAttribute方法?
事务切面
BeanFactoryTransactionAttributeSourceAdvisor继承自AbstractBeanFactoryPointcutAdvisor,重要的是定义了切点为TransactionAttributeSourcePointcut。
1 | public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor { |
切点需要的事务属性源即上面创建的AnnotationTransactionAttributeSource。匹配是否事务管理由TransactionAttributeSourcePointcut中的matches方法决定。
1 |
|
getTransactionAttribute方法执行的是AnnotationTransactionAttributeSource父类AbstractFallbackTransactionAttributeSource中的方法
1 | public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) { |
这里增加了一层缓存,第一次调用时执行computeTransactionAttribute方法
1 | protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) { |
@Transactional的优先级是:方法注解 > 类注解,这里的findTransactionAttribute执行的类就是AnnotationTransactionAttributeSource。
切面类配置完成后,需要绑定到Bean的生命周期中,这样在Bean创建时执行AOP代理,因此我们需要自动代理配置(关于自动代理,请见Spring源码-AOP(六)-自动代理与DefaultAdvisorAutoProxyCreator)。
基础自动代理
在tx:annotation-driven解析的开始,就注册了AOP的自动代理。
1 | AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element); |
由AopConfigUtils统一配置
1 | public static void registerAutoProxyCreatorIfNecessary( |
自动代理BeanDefinition配置为InfrastructureAdvisorAutoProxyCreator,只对Advisor的role为ROLE_INFRASTRUCTURE代理
1 | public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, |
InfrastructureAdvisorAutoProxyCreator继承AbstractAdvisorAutoProxyCreator,重写isEligibleAdvisorBean方法,判断适合的Advisor。
1 | protected boolean isEligibleAdvisorBean(String beanName) { |
自动代理的核心基类AbstractAutoProxyCreator实现了SmartInstantiationAwareBeanPostProcessor接口,在Bean初始化完成后,查找所有Advisor,并过滤切点包含自己的Advisor,详细时间见Spring源码-AOP(六)-自动代理与DefaultAdvisorAutoProxyCreator)。
对于事务拦截器TransactionInterceptor的实现过程已经在Spring事务管理(二)-TransactionProxyFactoryBean原理说明了,这里就不赘述了。