• Spring源码解析(十一):spring事务配置类源码


    Spring源码系列文章

    Spring源码解析(一):环境搭建

    Spring源码解析(二):bean容器的创建、默认后置处理器、扫描包路径bean

    Spring源码解析(三):bean容器的刷新

    Spring源码解析(四):单例bean的创建流程

    Spring源码解析(五):循环依赖

    Spring源码解析(六):bean工厂后置处理器ConfigurationClassPostProcessor

    Spring源码解析(七):bean后置处理器AutowiredAnnotationBeanPostProcessor

    Spring源码解析(八):bean后置处理器CommonAnnotationBeanPostProcessor

    Spring源码解析(九):AOP源码之@Aspect所有相关注解解析

    Spring源码解析(十):spring整合mybatis源码

    Spring源码解析(十一):spring事务配置类源码

    Spring源码解析(十二):TransactionInterceptor事务拦截器


    一、编程式事务

    1、基础使用

    • TransactionManager 管理事务对象
    @Bean
    public TransactionManager transactionManager() {
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(dataSource());
        return dataSourceTransactionManager;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • TransactionDefinition 事务的属性对象
    @Bean
    public TransactionDefinition transactionDefinition() {
        return new DefaultTransactionDefinition();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 开启事务(获取事务)、提交事务、回滚事务
    // 通过事务管理器开启一个事务
    TransactionStatus transactionStatus = transactionManager.getTransaction(transactionDefinition);
    try {
        // 完成自己的业务逻辑
    }
    catch (MyException ex) {
        // 出现异常,进行回滚
        transactionManager.rollback(transactionStatus);
        throw ex;
    }
    // 提交事务
    transactionManager.commit(transactionStatus);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2、PlatformTransactionManager

    • 定义了完成一个事务必须的三个步骤:开启事务、提交事务、回滚事务
    • 抽象父类AbstractPlatformTransactionManager
      • 主要用作事务管理的模板
      • 实现了事务的传播行为以及跟事务相关的同步管理
    • 开启事务的方法就是通过一个TransactionDefinition来获取一个TransactionStatus类型的对象
    public interface PlatformTransactionManager extends TransactionManager {
    	// 开启事务
        TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;
    	
        // 提交事务
        void commit(TransactionStatus status) throws TransactionException;
    	
        // 回滚事务
        void rollback(TransactionStatus status) throws TransactionException;
    }
    
    // 标记接口
    public interface TransactionManager {
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    PlatformTransactionManager的实现类

    在这里插入图片描述
    AbstractPlatformTransactionManager,Spring提供的一个事务管理的基类,提供了事务管理的模板,实现了Spring事务管理的一个标准流程

    1. 判断当前是否已经存在一个事务
    2. 应用合适的事务传播行为
    3. 在必要的时候挂起/恢复事务
    4. 提交时检查事务是否被标记成为rollback-only
    5. 在回滚时做适当的修改(是执行真实的回滚/还是将事务标记成rollback-only
    6. 触发注册的同步回调

    AbstractPlatformTransactionManager提供了四个常见的子类,其说明如下

    在这里插入图片描述

    3、TransactionDefinition

    public interface TransactionDefinition {
    	
        // 定义了7中事务的传播机制
    	int PROPAGATION_REQUIRED = 0;
    	int PROPAGATION_SUPPORTS = 1;
    	int PROPAGATION_MANDATORY = 2;
    	int PROPAGATION_REQUIRES_NEW = 3;
    	int PROPAGATION_NOT_SUPPORTED = 4;
    	int PROPAGATION_NEVER = 5;
    	int PROPAGATION_NESTED = 6;
    
        // 4种隔离级别,-1代表的是使用数据库默认的隔离级别
        // 比如在MySQL下,使用的就是ISOLATION_REPEATABLE_READ(可重复读)
    	int ISOLATION_DEFAULT = -1;
    	int ISOLATION_READ_UNCOMMITTED = 1;  
    	int ISOLATION_READ_COMMITTED = 2; 
    	int ISOLATION_REPEATABLE_READ = 4; 
    	int ISOLATION_SERIALIZABLE = 8;  
        
        // 事务的超时时间,默认不限制时间
    	int TIMEOUT_DEFAULT = -1;
    	
        // 提供了对上面三个属性的get方法
    	default int getPropagationBehavior() {
    		return PROPAGATION_REQUIRED;
    	}
    	default int getIsolationLevel() {
    		return ISOLATION_DEFAULT;
    	}
    	default int getTimeout() {
    		return TIMEOUT_DEFAULT;
    	}
    	
        // 事务是否是只读的,默认不是
    	default boolean isReadOnly() {
    		return false;
    	}
        
        // 事务的名称
    	@Nullable
    	default String getName() {
    		return null;
    	}
        
        // 返回一个只读的TransactionDefinition
        // 只对属性提供了getter方法,所有属性都是接口中定义的默认值
    	static TransactionDefinition withDefaults() {
    		return StaticTransactionDefinition.INSTANCE;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 有些是数据库层面本身就有的,例如隔离级别、是否只读、超时时间、名称
    • 也有些是Spring赋予的,例如事务的传播机制

    Spring中一共定义了7种事务的传播机制

    • TransactionDefinition.PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务(默认
    • TransactionDefinition.PROPAGATION_REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则把当前事务挂起
    • TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行
    • TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起
    • TransactionDefinition.PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常
    • TransactionDefinition.PROPAGATION_MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常
    • TransactionDefinition.PROPAGATION_NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于默认方式

    TransactionDefinition默认实现类DefaultTransactionDefinition

    • 为定义属性提供了默认值
    public class DefaultTransactionDefinition implements TransactionDefinition{
    	...
    
    	// 默认的传播机制为required,没有事务新建一个事务
    	// 有事务的话加入当前事务
    	private int propagationBehavior = PROPAGATION_REQUIRED;
    	
    	// 隔离级别跟数据库默认的隔离级别一直
    	private int isolationLevel = ISOLATION_DEFAULT;
    	
    	// 默认为-1,不设置超时时间
    	private int timeout = TIMEOUT_DEFAULT;
    	
    	// 默认不是只读的
    	private boolean readOnly = false;
    
    	...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    4、TransactionStatus

    • 这个接口主要用于描述Spring事务的状态,其继承关系如下:

    在这里插入图片描述

    • TransactionExecution,这个接口也是用于描述事务的状态
    // 判断当前事务是否是一个新的事务
    // 不是一个新事务的话,那么需要加入到已经存在的事务中
    boolean isNewTransaction();
    
    // 事务是否被标记成RollbackOnly
    // 如果被标记成了RollbackOnly,意味着事务只能被回滚
    void setRollbackOnly(); 
    boolean isRollbackOnly();
    
    // 是否事务完成,回滚或提交都意味着事务完成了
    boolean isCompleted();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • SavepointManager,定义了管理保存点(Savepoint)的方法
    • 隔离级别为NESTED时就是通过设置回滚点来实现的
    // 创建保存点
    Object createSavepoint() throws TransactionException;
    
    // 回滚到指定保存点
    void rollbackToSavepoint(Object savepoint) throws TransactionException;
    
    // 移除回滚点
    void releaseSavepoint(Object savepoint) throws TransactionException;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • TransactionStatus,继承了上面这些接口,额外提供了两个方法
    //用于判断当前事务是否设置了保存点
    boolean hasSavepoint();
    
    // 这个方法复写了父接口Flushable中的方法
    // 主要用于刷新会话
    // 对于Hibernate/jpa而言就是调用了其session/entityManager的flush方法
    void flush();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    总结:

    • TransactionDefinition的主要作用是给出一份事务属性的定义,然后事务管理器根据给出的定义来创建事务
    • TransactionStatus主要是用来描述创建后的事务的状态

    二、声明式事务注册bean

    1、基本使用

    • spring整合mybatis并添加事务配置和使用
    @Configuration // 声明该类是核心配置类
    @ComponentScan("com.xc") // 开启spring注解扫描
    @MapperScan("com.xc.mapper") // MyBatis扫描Mapper接口
    @EnableTransactionManagement
    public class MybatisConfig {
    
        @Bean
        public DataSource dataSource() {
            DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource();
            driverManagerDataSource.setPassword("root");
            driverManagerDataSource.setUsername("root");
            driverManagerDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
            driverManagerDataSource.setUrl("jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false&allowPublicKeyRetrieval=true");
            return driverManagerDataSource;
        }
    
        @Bean
        public SqlSessionFactoryBean sqlSessionFactoryBean() {
            SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
            sqlSessionFactoryBean.setDataSource(dataSource());
            return sqlSessionFactoryBean;
        }
    
         // 使用Spring中的DataSourceTransactionManager管理事务
         @Bean
         public DataSourceTransactionManager transactionManager() {
             DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
             dataSourceTransactionManager.setDataSource(dataSource());
             return dataSourceTransactionManager;
         }
    
    	// 执行操作
        public static void main(String[] args) {
            ApplicationContext context = new AnnotationConfigApplicationContext(MybatisConfig.class);
            UserMapper userMapper = context.getBean(UserMapper.class);
            User user = new User(200,"李四");
            userMapper.insertOne(user);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 通过开启AOP自动代理并向容器中注册事务需要的通知(Transaction Advisor
    • 其内部也是调用了TransactionManager的方法
    • 主要涉及到两个核心注解
      • @EnableTransactionManagement
      • @Transactional

    2、@EnableTransactionManagement

    • Spring事务管理的入口就是@EnableTransactionManagement注解
    • 与之前讲过的@EnableAspectJAutoProxy很相似
      • 可以选择使用jdk或cglib代理
      • 都通过@Import注册bean
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import(TransactionManagementConfigurationSelector.class)
    public @interface EnableTransactionManagement {
    	
    	// 是否使用cglib代理,默认是jdk代理
    	boolean proxyTargetClass() default false;
    	
        // 使用哪种代理模式,Spring AOP还是AspectJ
    	AdviceMode mode() default AdviceMode.PROXY;
    	
        // 为了完成事务管理,会向容器中添加通知
        // 这个order属性代表了通知的执行优先级
        // 默认是最低优先级
    	int order() default Ordered.LOWEST_PRECEDENCE;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    TransactionManagementConfigurationSelector

    • 核心内容就是注册AutoProxyRegistrarProxyTransactionManagementConfiguration
    /**
     * 子类实现了AdviceModeImportSelector,泛型类型为@EnableTransactionManagement注解
     * 重写了selectImports(AdviceMode adviceMode)方法
     */
    public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
    
        /**
         * 如果mode是PROXY,那么返回AutoProxyRegistrar和ProxyTransactionManagementConfiguration
         * 如果mode是ASPECTJ,那么返回AspectJ(Jta)TransactionManagementConfiguration
         */
        @Override
        protected String[] selectImports(AdviceMode adviceMode) {
            switch (adviceMode) {
                case PROXY:
                    //一般都是PROXY,因此将会注册AutoProxyRegistrar和ProxyTransactionManagementConfiguration的bean定义,进行动态代理
                    return new String[]{AutoProxyRegistrar.class.getName(),
                            ProxyTransactionManagementConfiguration.class.getName()};
                case ASPECTJ:
                    //支持Aspectj的静态代理织入
                    return new String[]{determineTransactionAspectClass()};
                default:
                    //其他值则返回null,将会抛出异常
                    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);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 父类AdviceModeImportSelector实现了ImportSelector接口
    • 通用基类,根据注解的AdviceMode来选择注册不同的bean定义
    /**
     * 这是一个通用基类,用于根据AdviceMode来选择注册不同的bean定义,该基类被用于广泛的支持@Enable*注解
     * 比如@EnableAsync、@EnableCaching、@EnableTransactionManagement(需要spring-tx依赖)
     *
     * @param  注解类型泛型
     */
    public abstract class AdviceModeImportSelector<A extends Annotation> implements ImportSelector {
    
        /**
         * AdviceMode属性的默认属性名字为"mode"
         */
        public static final String DEFAULT_ADVICE_MODE_ATTRIBUTE_NAME = "mode";
    
    
        /**
         * 获取AdviceMode属性的属性名,默认为"mode",子类可以覆盖重写
         */
        protected String getAdviceModeAttributeName() {
            return DEFAULT_ADVICE_MODE_ATTRIBUTE_NAME;
        }
    
        /**
         * 该方法就是核心方法,在解析@Import注解时就会自动调用
         * 

    * 该方法首先会校验指定的注解中是否存在类型为AdviceMode名字为getAdviceModeAttributeName()返回值的属性 * 然后会调用另一个selectImports(AdviceMode adviceMode)方法,该方法被子类重写,用于根据mode值判断应该使用哪些bean */ @Override public final String[] selectImports(AnnotationMetadata importingClassMetadata) { //获取确定的泛型类型 Class<?> annType = GenericTypeResolver.resolveTypeArgument(getClass(), AdviceModeImportSelector.class); Assert.state(annType != null, "Unresolvable type argument for AdviceModeImportSelector"); //获取该泛型注解的属性集合 AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(importingClassMetadata, annType); if (attributes == null) { throw new IllegalArgumentException(String.format( "@%s is not present on importing class '%s' as expected", annType.getSimpleName(), importingClassMetadata.getClassName())); } //从属性集合中根据AdviceMode属性的属性名获取属性值 AdviceMode adviceMode = attributes.getEnum(getAdviceModeAttributeName()); //调用selectImports(AdviceMode adviceMode)方法选择合适bean,该方法被子类重写 String[] imports = selectImports(adviceMode); //不能为null if (imports == null) { throw new IllegalArgumentException("Unknown AdviceMode: " + adviceMode); } return imports; } /** * 根据给定的AdviceMode确定应导入哪些类,该方法应被子类重写 *

    * 返回null将会抛出IllegalArgumentException异常. */ @Nullable protected abstract String[] selectImports(AdviceMode adviceMode); }

    3、AutoProxyRegistrar注册自动代理创建者

    • 这个类实现了ImportBeanDefinitionRegistrar,它的作用是向容器中注册别的BeanDefinition
    • 直接关注它的registerBeanDefinitions方法即可
    // 	AnnotationMetadata,代表的是AutoProxyRegistrar的导入类的元信息
    // 既包含了类元信息,也包含了注解元信息
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        boolean candidateFound = false;
        // 获取@EnableTransactionManagement所在配置类上的注解元信息
        Set<String> annTypes = importingClassMetadata.getAnnotationTypes();
        // 遍历注解
        for (String annType : annTypes) {
            // 可以理解为将注解中的属性转换成一个map
            AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annType);
            if (candidate == null) {
                continue;
            }
            // 直接从map中获取对应的属性
            Object mode = candidate.get("mode");
            Object proxyTargetClass = candidate.get("proxyTargetClass");
    
            // mode,代理模型,一般都是SpringAOP
            // proxyTargetClass,是否使用cglib代理
            if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() &&
                Boolean.class == proxyTargetClass.getClass()) {
    
                // 注解中存在这两个属性,并且属性类型符合要求,表示找到了合适的注解
                candidateFound = true;
    
                // 实际上会往容器中注册一个InfrastructureAdvisorAutoProxyCreator
                if (mode == AdviceMode.PROXY) {
                    AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
                    if ((Boolean) proxyTargetClass) {
                        AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
                        return;
                    }
                }
            }
        }
        // ......
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    注册核心类的方法栈

    在这里插入图片描述

    @EnableTransactionManagement与@EnableAspectJAutoProxy对比

    • 查看注册AspectJ自动代理类的方法调用栈
    • 调用方法一样,只是事务注册InfrastructureAdvisorAutoProxyCreator.class,AspectJ注册AnnotationAwareAspectJAutoProxyCreator.class

    在这里插入图片描述

    • AopConfigUtils类查看不同自动代理注册器下标,AnnotationAwareAspectJAutoProxyCreator最大,优先注册

    在这里插入图片描述

    • InfrastructureAdvisorAutoProxyCreator只会使用容器内部定义的Advisor
    • 但是AnnotationAwareAspectJAutoProxyCreator会使用所有实现了Advisor接口的通知
    • 所有后者可以覆盖(替换)前者

    4、ProxyTransactionManagementConfiguration注册事务管理bean

    类图:

    在这里插入图片描述

    AbstractTransactionManagementConfiguration抽象父类

    @Configuration
    public abstract class AbstractTransactionManagementConfiguration implements ImportAware {
    
    	@Nullable
    	protected AnnotationAttributes enableTx;
    
    	@Nullable
    	protected TransactionManager txManager;
    
    	// 这个方法就是获取@EnableTransactionManagement的属性
        // importMetadata:就是@EnableTransactionManagement这个注解所在类的元信息
    	@Override
    	public void setImportMetadata(AnnotationMetadata importMetadata) {
            // 将EnableTransactionManagement注解中的属性对存入到map中
            // AnnotationAttributes实际上就是个map
    		this.enableTx = AnnotationAttributes.fromMap(importMetadata.getAnnotationAttributes(EnableTransactionManagement.class.getName(), false));
            // 这里可以看到,限定了导入的注解必须使用@EnableTransactionManagement
            if (this.enableTx == null) {
                throw new IllegalArgumentException(
                    "@EnableTransactionManagement is not present on importing class " + importMetadata.getClassName());
            }
    	}
    	
        // 我们可以配置TransactionManagementConfigurer
        // 通过TransactionManagementConfigurer向容器中注册一个事务管理器
        // 一般不会这么使用,更多的是通过@Bean的方式直接注册
    	@Autowired(required = false)
    	void setConfigurers(Collection<TransactionManagementConfigurer> configurers) {
    		// .....
    		TransactionManagementConfigurer configurer = configurers.iterator().next();
    		this.txManager = configurer.annotationDrivenTransactionManager();
    	}
    	
        // 向容器中注册一个TransactionalEventListenerFactory
        // 这个类用于处理@TransactionalEventListener注解
        // 可以实现对事件的监听,并且在事务的特定阶段对事件进行处理
    	@Bean(name = TransactionManagementConfigUtils.TRANSACTIONAL_EVENT_LISTENER_FACTORY_BEAN_NAME)
    	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    	public static TransactionalEventListenerFactory transactionalEventListenerFactory() {
    		return new TransactionalEventListenerFactory();
    	}
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    ProxyTransactionManagementConfiguration核心配置类

    // proxyBeanMethods=false,意味着不对配置类生成代理对象
    @Configuration(proxyBeanMethods = false)
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
    	
        // 注册了一个BeanFactoryTransactionAttributeSourceAdvisor
        // advisor就是一个绑定了切点的通知
        // 可以看到通知就是TransactionInterceptor
        // 切点会通过TransactionAttributeSource去解析@Transacational注解
        // 只会对有这个注解的方法进行拦截
    	@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
        // BeanDefinition的角色是一个基础设施类
    	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    	public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(
    			TransactionAttributeSource transactionAttributeSource, TransactionInterceptor transactionInterceptor) {
    		
    		BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
    		advisor.setTransactionAttributeSource(transactionAttributeSource);
    		advisor.setAdvice(transactionInterceptor);
    		if (this.enableTx != null) {
    			advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
    		}
    		return advisor;
    	}
    	
        // 注册一个AnnotationTransactionAttributeSource
        // 这个类的主要作用是用来解析@Transacational注解
    	@Bean
    	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    	public TransactionAttributeSource transactionAttributeSource() {
    		return new AnnotationTransactionAttributeSource();
    	}
    	
        // 事务是通过AOP实现的,AOP的核心就是拦截器
        // 这里就是注册了实现事务需要的拦截器
    	@Bean
    	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    	public TransactionInterceptor transactionInterceptor(TransactionAttributeSource transactionAttributeSource) {
    		TransactionInterceptor interceptor = new TransactionInterceptor();
    		// 将AnnotationTransactionAttributeSource注解事务属性源set到事务拦截器对象中
    		interceptor.setTransactionAttributeSource(transactionAttributeSource);
    		if (this.txManager != null) {
    			interceptor.setTransactionManager(this.txManager);
    		}
    		return interceptor;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    总结:

    • ProxyTransactionManagementConfiguration类是一个@Configuration配置类
    • 通过内部的@Bean方法向容器注入一系列与AOP事务相关的一些基础bean定义
      • BeanFactoryTransactionAttributeSourceAdvisor事务通知增强器
      • AnnotationTransactionAttributeSource注解事务属性源
      • TransactionInterceptor事务拦截器(核心内容)
      • TransactionalEventListenerFactory事务事件监听器工厂

    三、创建代理对象

    在这里插入图片描述

    • 由图可知,先执行事务拦截器,再执行切面通知的拦截器,下一章节进入事务拦截器的invoke方法
  • 相关阅读:
    3.消息队列全面总结——ActiveMq,RabbitMQ,RocketMq,Kafa
    Canonical标签在SEO中重要作用
    TypeScript
    8 个关于提高你 Flutter 移动程序安全性的建议
    node.js共享输液检测系统毕业设计源码131105
    win32汇编源程序结构
    ConcurrentModificationException日志关键字报警引发的思考
    2023年个人怎么报考湖北建筑安全员C2C3证-叙后尘
    西工大2022数学竞赛极限专题的练习记录
    vue.js插槽的定义和使用
  • 原文地址:https://blog.csdn.net/qq_35512802/article/details/132789097