SpringBoot 源码解析 (八)----- Spring Boot 精髓:事务源码解析

本文内容纲要:

- SSM使用事务

- 导入JDBC依赖包

- 配置版事务

- 注解版事务

- SpringBoot" title="SpringBoot">SpringBoot自动配置事务

- 引入JDBC

- DataSourceTransactionManagerAutoConfiguration

- TransactionAutoConfiguration

- mybatis-spring-boot-starter

- 总结

本篇来讲一下SpringBoot是怎么自动开启事务的,我们先来回顾一下以前SSM中是如何使用事务的

SSM使用事务

导入JDBC依赖包

众所周知,凡是需要跟数据库打交道的,基本上都要添加jdbc的依赖,在Spring项目中,加入的是spring-jdbc依赖:

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-jdbc</artifactId>

</dependency>

配置版事务

在使用配置文件的方式中,通常会在Spring的配置文件中配置事务管理器,并注入数据源:

<!-- 注册数据源 -->

<bean id="dataSource" class="...">

<property name="" value=""/>

</bean>

<!-- 注册事务管理器 -->

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

<property name="dataSource" ref="dataSource" />

</bean>

<!-- 开启事务注解 -->

<tx:annotation-driven transaction-manager="txManager" />

接下来可以直接在业务层Service的方法上或者类上添加**@Transactional**。

注解版事务

首先需要注册两个Bean,分别对应上面Spring配置文件中的两个Bean:

@EnableTransactionManagement//重要

@Configuration

public class TxConfig {

@Bean

public DataSource dataSource() {

ComboPooledDataSource dataSource = new ComboPooledDataSource();

dataSource.setUser("...");

dataSource.setPassword("...");

dataSource.setDriverClass("...");

dataSource.setJdbcUrl("...");

return dataSource;

}

//重要

@Bean

public PlatformTransactionManager platformTransactionManager() {

return new DataSourceTransactionManager(dataSource());//放入数据源

}

}

我们看到往Spring容器中注入了DataSource 和PlatformTransactionManager 对象,并且通过@EnableTransactionManagement注解开启了事务,和上面的XML配置是一一对应的。PlatformTransactionManager这个Bean非常重要,要使用事务管理,就必须要在IOC容器中注册一个事务管理器。

public interface PlatformTransactionManager {

//获取一个Transaction

TransactionStatus getTransaction(TransactionDefinition var1) throws TransactionException;

//提交事务

void commit(TransactionStatus var1) throws TransactionException;

//回滚事务

void rollback(TransactionStatus var1) throws TransactionException;

}

我们看到事务管理器的作用就是获取事务,提交回滚事务。DataSourceTransactionManager是PlatformTransactionManager的一个实现类,大家可以看看我以前的文章spring5 源码深度解析----- Spring事务 是怎么通过AOP实现的?(100%理解Spring事务) 看一下Spring的声明式事务的源码。下面我们来看看SpringBoot是如何自动配置事务的

SpringBoot自动配置事务

引入JDBC

众所周知,在SpringBoot中凡是需要跟数据库打交道的,基本上都要显式或者隐式添加jdbc的依赖:

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-jdbc</artifactId>

</dependency>

也就是jdbc的场景启动器,我们点进去看看

其实也是引入了spring-jdbc的依赖,接下来我们要看两个重要的事务自动配置类

DataSourceTransactionManagerAutoConfiguration

我们看到在spring.factories中配置了事务管理器自动配置类DataSourceTransactionManagerAutoConfiguration,我们进去看看

1 @Configuration

2 //在类路径下有这个类存在PlatformTransactionManager时,这个配置类才会生效

3 //而前面我们已经引入了spring-boot-starter-jdbc,那自然是存在了

4 @ConditionalOnClass({ JdbcTemplate.class, PlatformTransactionManager.class })

5 @AutoConfigureOrder(Ordered.LOWEST_PRECEDENCE)

6 @EnableConfigurationProperties(DataSourceProperties.class)

7 public class DataSourceTransactionManagerAutoConfiguration {

8

9 @Configuration

10 @ConditionalOnSingleCandidate(DataSource.class)

11 static class DataSourceTransactionManagerConfiguration {

12

13 private final DataSource dataSource;

14

15 private final TransactionManagerCustomizers transactionManagerCustomizers;

16

17 DataSourceTransactionManagerConfiguration(DataSource dataSource,

18 ObjectProvider<TransactionManagerCustomizers> transactionManagerCustomizers) {

19 this.dataSource = dataSource;

20 this.transactionManagerCustomizers = transactionManagerCustomizers

21 .getIfAvailable();

22 }

23

24 @Bean

25 //没有当Spring容器中不存在PlatformTransactionManager这个对象时,创建DataSourceTransactionManager

26 //也就是如果我们自定义了DataSourceTransactionManager并注入Spring容器,这里将不会执行

27 @ConditionalOnMissingBean(PlatformTransactionManager.class)

28 public DataSourceTransactionManager transactionManager(DataSourceProperties properties) {

29 //创建DataSourceTransactionManager注入Spring容器,并且把dataSource传进去

30 DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(this.dataSource);

31 if (this.transactionManagerCustomizers != null) {

32 this.transactionManagerCustomizers.customize(transactionManager);

33 }

34 return transactionManager;

35 }

36

37 }

38

39 }

很明显只要我们导入了spring-boot-starter-jdbc场景启动器,并且我们没有自定义DataSourceTransactionManager,那么事务管理器自动配置类DataSourceTransactionManagerAutoConfiguration会自动为我们创建DataSourceTransactionManager并注入Spring容器中。但是这还不够,我们前面还是需要通过**@EnableTransactionManagement开启事务呢**,如果不开启事务,@Transactional是不起任何作用的。下面我们就来看看是如何开启事务的

TransactionAutoConfiguration

我们看到在spring.factories中配置了事务自动开启配置类TransactionAutoConfiguration,我们进去看看

1 @Configuration

2 //和DataSourceTransactionManagerAutoConfiguration中是一样的

3 //引入了spring-boot-starter-jdbc,那自然是存在了PlatformTransactionManager

4 @ConditionalOnClass({PlatformTransactionManager.class})

5 //这个自动配置类必须要在DataSourceTransactionManagerAutoConfiguration这个自动配置类之后才能生效

6 //也就是前面我们已经往Spring容器中注入了DataSourceTransactionManager这个对象才执行这个配置类

7 @AutoConfigureAfter({JtaAutoConfiguration.class, HibernateJpaAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, Neo4jDataAutoConfiguration.class})

8 @EnableConfigurationProperties({TransactionProperties.class})

9 public class TransactionAutoConfiguration {

10 public TransactionAutoConfiguration() {

11 }

12

13 @Configuration

14 @ConditionalOnBean({PlatformTransactionManager.class})

15 @ConditionalOnMissingBean({AbstractTransactionManagementConfiguration.class})

16 public static class EnableTransactionManagementConfiguration {

17 public EnableTransactionManagementConfiguration() {

18 }

19

20 @Configuration

21 //重点:通过 @EnableTransactionManagement注解开启事务

22 //可以看到和我们自己使用@EnableTransactionManagement是一样的

23 @EnableTransactionManagement(

24 proxyTargetClass = true

25 )

26 @ConditionalOnProperty(

27 prefix = "spring.aop",

28 name = {"proxy-target-class"},

29 havingValue = "true",

30 matchIfMissing = true

31 )

32 public static class CglibAutoProxyConfiguration {

33 public CglibAutoProxyConfiguration() {

34 }

35 }

36

37 @Configuration

38 @EnableTransactionManagement(

39 proxyTargetClass = false

40 )

41 @ConditionalOnProperty(

42 prefix = "spring.aop",

43 name = {"proxy-target-class"},

44 havingValue = "false",

45 matchIfMissing = false

46 )

47 public static class JdkDynamicAutoProxyConfiguration {

48 public JdkDynamicAutoProxyConfiguration() {

49 }

50 }

51 }

52

53 @Configuration

54 @ConditionalOnSingleCandidate(PlatformTransactionManager.class)

55 public static class TransactionTemplateConfiguration {

56 private final PlatformTransactionManager transactionManager;

57

58 public TransactionTemplateConfiguration(PlatformTransactionManager transactionManager) {

59 this.transactionManager = transactionManager;

60 }

61

62 @Bean

63 @ConditionalOnMissingBean

64 public TransactionTemplate transactionTemplate() {

65 return new TransactionTemplate(this.transactionManager);

66 }

67 }

68 }

我们看到TransactionAutoConfiguration这个自动配置类必须要在DataSourceTransactionManagerAutoConfiguration这个配置类之后才能生效,也就是前面我们已经往Spring容器中注入了DataSourceTransactionManager这个对象才执行这个配置类,然后通过

@EnableTransactionManagement这个注解开启事务,其实和我们自己使用@EnableTransactionManagement是一样的

因此,只要我们在SpringBoot中引入了spring-boot-starter-jdbc这个场景启动器,就会帮我们自动开启事务了,我们只需要使用@Transactional就可以了

mybatis-spring-boot-starter

大多数时候我们在SpringBoot中会引入Mybatis这个orm框架,Mybaits的场景启动器如下

<dependency>

<groupId>org.mybatis.spring.boot</groupId>

<artifactId>mybatis-spring-boot-starter</artifactId>

<version>1.3.0</version>

</dependency>

我们点进去看看

我们看到mybatis-spring-boot-starter这个场景启动器是引入了spring-boot-starter-jdbc这个场景启动器的,因此只要我们在SpringBoot中使用Mybaits,是自动帮我们开启了Spring事务的

总结

springboot 开启事物很简单,只需要加一行注解**@Transactional**就可以了,前提你用的是jdbctemplate, jpa, Mybatis,这种常见的orm。

本文内容总结:SSM使用事务,导入JDBC依赖包,配置版事务,注解版事务,SpringBoot自动配置事务,引入JDBC,DataSourceTransactionManagerAutoConfiguration,TransactionAutoConfiguration,mybatis-spring-boot-starter,总结,

原文链接:https://www.cnblogs.com/java-chen-hao/p/11844523.html

以上是 SpringBoot 源码解析 (八)----- Spring Boot 精髓:事务源码解析 的全部内容, 来源链接: utcz.com/z/362708.html

回到顶部