Spring5.0源码深度解析之SpringBean声明事务底层实现原理

SpringAop基本原理和思想

1、事务保证数据一致性问题,只需要加上@Transactional 2、纯手写SpringAop环绕通知+手动事务就可以声明事务

基于Spring注解方式构建整合JDBC环境

@Repository
public class OrderDao {
    @Autowired()
    private JdbcTemplate jdbcTemplate;
    public void addOrder() {
        jdbcTemplate.update("insert into order_info values(null,'mayikt','zhangsan','1111')");
    }
}
@Configuration
@ComponentScan("com.mayikt")
// @EnableTransactionManagement 实际上帮助我们开启了aop
@EnableTransactionManagement
public class MyConfig {
    //注入到ioc容器中 beanid =dataSource class=DataSource类的完整路径地址
    // 配置我们的数据源
    @Bean
    public DataSource dataSource() {
        MysqlDataSource mysqlDataSource = new MysqlDataSource();
        mysqlDataSource.setUser("root");
        mysqlDataSource.setPassword("root");
        mysqlDataSource.setURL("jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8");
        mysqlDataSource.setDatabaseName("test");
        return mysqlDataSource;
    }
    /**
     * 注入JdbcTemplate
     */
    @Bean
    public JdbcTemplate jdbcTemplate() {
        return new JdbcTemplate(dataSource());
    }
    // 多数据源如何实现
    //@EnableTransactionManagement 开启事务注解
    @Bean
    public PlatformTransactionManager platformTransactionManager(){
         return  new DataSourceTransactionManager(dataSource());
    }
}
@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderDao orderDao;
    @Transactional
    public void addOrder() {
        try {
            orderDao.addOrder();
            int i = 1 / 0; // 如果报错的情况下肯定是会插入到数据库中
        } catch (Exception e) {
        }
    }
}
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.0.5.RELEASE</version>
    </dependency>

    <!-- mysql 依赖 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.46</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.0.5.RELEASE</version>
    </dependency>
</dependencies>

Spring声明事务底层源码分析

@EnableTransactionManagement//开启事务
@Import({TransactionManagementConfigurationSelector.class})
TransactionManagementConfigurationSelector的祖宗是ImportSelector
public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar {//向IOC容器中注入Bean对象
public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
    return registerAutoProxyCreatorIfNecessary(registry, (Object)null);
}
public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, @Nullable Object source) {
    return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
}

将InfrastructureAdvisorAutoProxyCreator注入到IOC容器中:

下面回到

BeanId:transactionInterceptor;value为:TransactionInterceptor这个对象

打印所有注册的Bean

org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.context.annotation.internalRequiredAnnotationProcessor org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.event.internalEventListenerProcessor org.springframework.context.event.internalEventListenerFactory myConfig orderDao orderServiceImpl org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration org.springframework.transaction.config.internalTransactionAdvisor transactionAttributeSource transactionInterceptor【】【】【】【】这里 org.springframework.transaction.config.internalTransactionalEventListenerFactory dataSource jdbcTemplate platformTransactionManager org.springframework.aop.config.internalAutoProxyCreator【】【】【】【】这里

加上@EnableTransactionManagement这个注解将 :transactionInterceptor,和org.springframework.aop.config.internalAutoProxyCreator这两个类注入到IOC容器中

下面重点分析这两个类【transactionInterceptor】,【internalAutoProxyCreator

我们一旦吧这个类:InfrastructureAdvisorAutoProxyCreator,Bean对象在初始化时,会判断是否需要创建代理类。

InfrastructureAdvisorAutoProxyCreator的祖宗就是AbstractAutoProxyCreator

@EnableTransactionManagement这个注解,实际帮我门开启了AOP

public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
    if (bean != null) {
        Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
        if (!this.earlyProxyReferences.contains(cacheKey)) {
            return this.wrapIfNecessary(bean, beanName, cacheKey);
        }
    }

    return bean;
}

springaop在事务进行调用的时候会走transactionInterceptor进行拦截

执行目标方法,进入invoke()

Spring声明事务源码分析

1.@EnableTransactionManagement开启到我们的事务 2.@Import(TransactionManagementConfigurationSelector.class) 3. AdviceMode mode() default AdviceMode.PROXY;默认使用 PROXY选择器 4.return new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()}; 5.AutoProxyRegistrar会将InfrastructureAdvisorAutoProxyCreator注册到IOC容器中; ##BeanId=internalAutoProxyCreator ##value=InfrastructureAdvisorAutoProxyCreator 6.ProxyTransactionManagementConfiguration将以下对象注入到IOC容器中: ##BeanId:transactionInterceptor ##value:TransactionInterceptor对象

重点分析:InfrastructureAdvisorAutoProxyCreator、tansactionInterceptor

InfrastructureAdvisorAutoProxyCreator祖宗就是我们的后置处理器 Bean对象在初始化之后都会判断是否需要创建代理类(根据是否有加上@Transactional) InfrastructureAdvisorAutoProxyCreator 祖宗就是AbstractAutoProxyCreator前置和后置处理

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券