• Spring事务-底层原理分析


    目录

    一、开启基于注解的事务管理

    二、解析

    1、@EnableTransactionManagement

    2、TransactionManagementConfigurationSelector

     3、AutoProxyRegistrar

     4、InfrastructureAdvisorAutoProxyCreator

     5、ProxyTransactionManagementConfiguration

    5.1 BeanFactoryTransactionAttributeSourceAdvisor

    5.2 TransactionAttributeSource

    5.3 TransactionInterceptor

    三、运行步骤

    四、测试类


    一、开启基于注解的事务管理

    在配置类中加上@EnableTransactionManagement注解即可开启。

    二、解析

    1、@EnableTransactionManagement

    注解使用了@Import功能向容器导入组件

    2、TransactionManagementConfigurationSelector


    这个类是一个ImportSelector类型实现类,利用ImportSelector功能,默认向容器导入2个组件,分别是【AutoProxyRegistrar】、【ProxyTransactionManagementConfiguration

     3、AutoProxyRegistrar

    AutoProxyRegistrarImportBeanDefinitionRegistrar实现类,容器在注册组件时调用registerBeanDefinitions方法。AutoProxyRegistrar利用registerBeanDefinitions方法向容器导入InfrastructureAdvisorAutoProxyCreator组件

     4、InfrastructureAdvisorAutoProxyCreator

    打开InfrastructureAdvisorAutoProxyCreator源码可发现该类是一个SmartInstantiationAwareBeanPostProcessor类型的实现类。

    在容器创建对象完成初始化后通过调用postProcessAfterInitialization()方法判断该对象是否含有符合条件的Advisor增强器,若是符合,则将对象包装成代理对象返回给IOC容器

     进入wrapIfNecessary方法中,getAdvicesAndAdvisorsForBean方法是返回适用于对象的增强器

    通过createProxy方法创建代理对象并返回,该代理对象包含了对象的增强器、目标对象等信息。

     5、ProxyTransactionManagementConfiguration

    这是一个配置类,主要是向容器注册
    BeanFactoryTransactionAttributeSourceAdvisor事务增强器、AnnotationTransactionAttributeSource事务注解属性、
    TransactionInterceptor事务拦截器
    

    可在容器中注册TransactionManagementConfigurer类型对象,指定默认事务管理器,通过ProxyTransactionManagementConfiguration的父类AbstractTransactionManagementConfigurationsetConfigurers方法完成注入。

    (一般都是通过@Bean直接往容器注册事务管理器,若是注册多个事务管理器,可通过@Transactionalvalue属性指定事务管理器)

    5.1 BeanFactoryTransactionAttributeSourceAdvisor

     这是一个Spring事务增强器Advisor,用于容器创建对象完成初始化后,判断对象是否需要事务增强,从而将对象包装成代理对象。
    增强器配置TransactionInterceptor事务拦截器TransactionAttributeSource事务注解属性

    5.2 TransactionAttributeSource

    这是一个解析@Transactional注解属性的解析器

    5.3 TransactionInterceptor

    这是一个事务拦截器,后续代理对象调用具体方法,会生成对应的拦截器链,通过拦截器链实现事务操作。

     拦截器链调用invoke方法的invokeWithinTransaction方法中实现事务操作

     

    三、运行步骤

    代理对象调用方法具体运行步骤参考SpringAOP-底层原理解析_Just-Today的博客-CSDN博客,原理大致一致

    四、测试类

    1. package com.mzp.component.tx;
    2. import org.springframework.beans.factory.annotation.Autowired;
    3. import org.springframework.jdbc.core.JdbcTemplate;
    4. import org.springframework.stereotype.Repository;
    5. import java.util.UUID;
    6. @Repository
    7. public class TestDao {
    8. @Autowired
    9. private JdbcTemplate jdbcTemplate;
    10. public void insert(){
    11. String id = UUID.randomUUID().toString();
    12. String sql = "insert into person values(?,?,?)";
    13. jdbcTemplate.update(sql,id, "jaclk", 1);
    14. }
    15. }
    1. package com.mzp.component.tx;
    2. import org.springframework.beans.factory.annotation.Autowired;
    3. import org.springframework.stereotype.Service;
    4. import org.springframework.transaction.annotation.Transactional;
    5. @Service
    6. public class TestService {
    7. @Autowired
    8. private TestDao testDao;
    9. @Transactional
    10. public void insert(){
    11. testDao.insert();
    12. int i = 1/0;
    13. }
    14. }
    1. package com.mzp.component.config;
    2. import com.alibaba.druid.pool.DruidDataSource;
    3. import org.springframework.beans.factory.annotation.Value;
    4. import org.springframework.context.annotation.Bean;
    5. import org.springframework.context.annotation.ComponentScan;
    6. import org.springframework.context.annotation.Configuration;
    7. import org.springframework.context.annotation.PropertySource;
    8. import org.springframework.jdbc.core.JdbcTemplate;
    9. import org.springframework.jdbc.datasource.DataSourceTransactionManager;
    10. import org.springframework.transaction.PlatformTransactionManager;
    11. import org.springframework.transaction.annotation.EnableTransactionManagement;
    12. import javax.sql.DataSource;
    13. @Configuration
    14. @EnableTransactionManagement
    15. @ComponentScan("com.mzp.component.tx")
    16. @PropertySource("datasource.properties")
    17. public class TxConfig {
    18. @Value("${jdbc.username}")
    19. private String username;
    20. @Value("${jdbc.password}")
    21. private String pass;
    22. @Value("${jdbc.driver}")
    23. private String driver;
    24. @Value("${jdbc.url}")
    25. private String url;
    26. @Bean
    27. public DataSource dataSource(){
    28. DruidDataSource druidDataSource = new DruidDataSource();
    29. druidDataSource.setUsername(username);
    30. druidDataSource.setPassword(pass);
    31. druidDataSource.setUrl(url);
    32. druidDataSource.setDriverClassName(driver);
    33. return druidDataSource;
    34. }
    35. @Bean
    36. public JdbcTemplate jdbcTemplate(){
    37. return new JdbcTemplate(dataSource());
    38. }
    39. @Bean
    40. public PlatformTransactionManager transactionManager(){
    41. return new DataSourceTransactionManager(dataSource());
    42. }
    43. }
    1. @Test
    2. public void test12(){
    3. ApplicationContext applicationContext = new AnnotationConfigApplicationContext(TxConfig.class);
    4. TestService testService = applicationContext.getBean(TestService.class);
    5. testService.insert();
    6. }

  • 相关阅读:
    onbuy买家号下单教程,自养买家号测评环境资源和核心优势!
    【计算机视觉 | 图像模型】常见的计算机视觉 image model(CNNs & Transformers) 的介绍合集(四)
    3.6 Redis缓存过期机制
    sqllab第二十六关通关笔记
    【JavaScript复习七】内置对象string截取字符串及其他方法
    csdn最新最全pytest系列——pluggy插件源码解读(一)HookspecMarker类和HookimplMarker类分析
    通过easyexcel实现数据导入功能
    8.12 PowerBI系列之DAX函数专题-分组内动态TopN和others
    golang1.21新特性速览
    dom xss->半自动化
  • 原文地址:https://blog.csdn.net/weixin_37607613/article/details/126155070