死磕Spring之AOP篇 - Spring 事务详解 (3)

Spring 事务底层就是通过 Spring AOP 实现的,可以在上面看到有一个 PointcutAdvisor 切面,关联的 Pointcut 内部有一个 TransactionAttributeSource 对象,会借助于 TransactionAnnotationParser 解析器解析 @Transactional 注解,将这个事务定义的一些属性封装成一个 TransactionDefinition 事务定义对象

Spring AOP 拦截处理在 TransactionInterceptor 事务拦截器中,先借助 PlatformTransactionManager 平台事务管理器创建 TransactionStatus 事务对象,里面包含了 Transaction 事务,将 autocommit 自动提交关闭,方法的执行也就处于一个事务中

事务的相关属性会保存在许多 ThreadLocal 中,例如 DataSource、Connection 和 SqlSession 等属性,交由一个 TransactionSynchronizationManager 事务同步管理器进行管理,所以说 Spring 事务仅支持在一个线程中完成

Spring 事务非常复杂,接下来我们逐步分析

@EnableTransactionManagement 注解驱动 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(TransactionManagementConfigurationSelector.class) public @interface EnableTransactionManagement { /** * 默认优先使用 JDK 动态代理 */ boolean proxyTargetClass() default false; /** * 默认使用 Spring AOP 代理模式 */ AdviceMode mode() default AdviceMode.PROXY; int order() default Ordered.LOWEST_PRECEDENCE; }

可以看到有一个 @Import 注解,它的值是一个 TransactionManagementConfigurationSelector 类,也就是说 Spring 事务的驱动入口在这里面,关于 @Import 注解的原理可查看我的 《死磕Spring之IoC篇 - @Bean 等注解的实现原理》 这篇文章

TransactionManagementConfigurationSelector

public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> { @Override protected String[] selectImports(AdviceMode adviceMode) { switch (adviceMode) { // 默认使用代理模式 case PROXY: return new String[]{ // 注册一个 InfrastructureAdvisorAutoProxyCreator 对象,目的是创建代理对象 AutoProxyRegistrar.class.getName(), // 【关键】注册一个 Spring 事务代理配置类 ProxyTransactionManagementConfiguration.class.getName()}; // 选择 AspectJ 模式 case ASPECTJ: return new String[]{determineTransactionAspectClass()}; default: return null; } } private String determineTransactionAspectClass() { return (ClassUtils.isPresent("javax.transaction.Transactional", getClass().getClassLoader()) ? TransactionManagementConfigUtils.JTA_TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME : TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME); } }

可以看到默认情况下会注册两个 Bean

AutoProxyRegistrar,注册一个 InfrastructureAdvisorAutoProxyCreator 对象,目的是创建代理对象,在讲解 Spring AOP 的时候讲述过,这里不再赘述

ProxyTransactionManagementConfiguration,一个 Spring 务代理配置类

ProxyTransactionManagementConfiguration

org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration,Spring 事务代理配置类,定义好一个 AOP 切面

@Configuration @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration { @Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME) @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() { // <1> 创建 PointcutAdvisor 对象,作为 @Transactional 注解的一个切面 BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor(); // <2> 【Pointcut】设置 AnnotationTransactionAttributeSource,被关联在 Pointcut 中 // 借助于 TransactionAnnotationParser 解析器解析 @Transactional 注解 advisor.setTransactionAttributeSource(transactionAttributeSource()); // <3> 【Advice】设置 Advice 为 TransactionInterceptor 事务拦截器 advisor.setAdvice(transactionInterceptor()); if (this.enableTx != null) { advisor.setOrder(this.enableTx.<Integer>getNumber("order")); } return advisor; } @Bean @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public TransactionAttributeSource transactionAttributeSource() { return new AnnotationTransactionAttributeSource(); } @Bean @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public TransactionInterceptor transactionInterceptor() { // 创建 TransactionInterceptor 事务拦截器(MethodInterceptor 对象) TransactionInterceptor interceptor = new TransactionInterceptor(); // 设置这个 AnnotationTransactionAttributeSource 对象,@Bean 注解标注的方法返回的都是同一个对象 interceptor.setTransactionAttributeSource(transactionAttributeSource()); if (this.txManager != null) { // 设置默认的事务管理器 interceptor.setTransactionManager(this.txManager); } return interceptor; } }

可以看到会注册三个 Bean:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zygsff.html