spring 事务部分共5篇文章
第一篇:spring中@EnableTransactionManager @Transactional注解实现机制
第二篇:spring boot中事务功能自动配置的加载过程分析
第三篇:spring@Transactional注解属性字段含义
第四篇:spring @Transactional如何测试事务注解生效
第五篇:spring及spring boot中事务相关知识的总结
本篇为第二篇
在spring boot中,默认是启用@EnableTransactionManagement注解的,下面对spring boot支持事务功能的加载过程进行解析
在spring boot中,在spring.factories中默认加载了
org.springframework.boot.test.autoconfigure.orm.jpa.AutoConfigureDataJpa=\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\
0. 自动@EnableTransactionManagement
启动spring应用上下文之后,其执行到
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
其会register embeddedServletContainerCustomizerBeanPostProcessor
其在resolveDependency的时候,会注册
org.springframework.transaction.config.internalTransactionAdvisor
其resolveDependency的时候,会注册
org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration
其执行initializeBean
之后会执行到ConfigurationClassPostProcessor的
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
if (bean instanceof ImportAware) {
ImportRegistry importRegistry = this.beanFactory.getBean(IMPORT_REGISTRY_BEAN_NAME, ImportRegistry.class);
AnnotationMetadata importingClass = importRegistry.getImportingClassFor(bean.getClass().getSuperclass().getName());
if (importingClass != null) {
((ImportAware) bean).setImportMetadata(importingClass);
}
}
return bean;
}
其中关键代码
((ImportAware) bean).setImportMetadata(importingClass);
在AbstractTransactionManagementConfiguration implement ImportAware中
@Override
public void setImportMetadata(AnnotationMetadata importMetadata) {
this.enableTx = AnnotationAttributes.fromMap( importMetadata.getAnnotationAttributes(EnableTransactionManagement.class.getName(), false));
}
加载了EnableTransactionManagement注解(即在spring boot中已经自动加载了@EnableTransactionManagement注解)
此时会引发一系列bean的加载,详见:spring中@EnableTransactionManager @Transactional注解实现机制
1. DataSourceAutoConfiguration
作用:创建DataSource bean,是在数据库加载的时候,就加载了
实际上最先要加载的类是DataSourceAutoConfiguration,
@Configuration
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({ Registrar.class, DataSourcePoolMetadataProvidersConfiguration.class })
public class DataSourceAutoConfiguration {}
DataSourceProperties
@ConfigurationProperties(prefix = "spring.datasource")
public class DataSourceProperties
implements BeanClassLoaderAware, EnvironmentAware, InitializingBean {}
2. HibernateJpaAutoConfiguration(JpaBaseConfiguration)
作用:创建PlatformTransactionManager
之后会逐渐注入@Configuration类下的@Bean
会执行到JpaBaseConfiguration的实现类HibernateJpaAutoConfiguration
其也依赖于DataSourceAutoConfiguration类
在TransactionAutoConfiguration加载之前要加载
JpaBaseConfiguration以及DataSourceTransactionManagerAutoConfiguration类
@Configuration
@ConditionalOnClass({ LocalContainerEntityManagerFactoryBean.class,
EnableTransactionManagement.class, EntityManager.class })
@Conditional(HibernateEntityManagerCondition.class)
@AutoConfigureAfter({ DataSourceAutoConfiguration.class })
public class HibernateJpaAutoConfiguration extends JpaBaseConfiguration {
}
执行到JpaBaseConfiguration类,会创建JpaBaseConfiguration中的类
注意其并没有@Configuration,但通过子类和父类的继承方式,也可以创建spring bean
@EnableConfigurationProperties(JpaProperties.class)
@Import(DataSourceInitializedPublisher.Registrar.class)
public abstract class JpaBaseConfiguration implements BeanFactoryAware {
@Bean
@ConditionalOnMissingBean(PlatformTransactionManager.class)
public PlatformTransactionManager transactionManager() {
return new JpaTransactionManager();
}
@Import,就是将DataSourceInitializedPublisher注册为spring bean
class DataSourceInitializedPublisher implements BeanPostProcessor {
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
if (bean instanceof DataSource) {
// Normally this will be the right DataSource
this.dataSource = (DataSource) bean;
}
if (bean instanceof JpaProperties) {
this.properties = (JpaProperties) bean;
}
return bean;
}
}
JpaProperties类
@ConfigurationProperties(prefix = "spring.jpa")
public class JpaProperties {
这也是我们在application.properties中设置所能生效的原因
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.properties.hibernate.type=trace
在这里初始化transactionManager,即使用JPA作为数据库访问技术时,spring boot使用的是JpaTransactionManager,而使用JDBC作为数据库访问技术时,spring boot使用的是DataSourceTransactionManager
Spring 的事务机制是用统一的机制来处理不同的数据访问技术的事务处理。
Spring 的事务机制提供了一个 PlatformTransactionManager 接口,不同的数据访问技术的事务使用不同的接口实现。
数据库访问技术 | 实现类 |
---|---|
JDBC | DataSourceTransactionManager |
JPA | JpaTransactionManager |
Hibernate | HibernateTransactionManager |
3. DataSourceTransactionManagerAutoConfiguration
如果PlatformTransactionManager不存在,这里来创建
@Configuration
@ConditionalOnClass({ JdbcTemplate.class, PlatformTransactionManager.class })
@AutoConfigureOrder(Ordered.LOWEST_PRECEDENCE)
public class DataSourceTransactionManagerAutoConfiguration {
@Bean
@ConditionalOnMissingBean(PlatformTransactionManager.class)
public DataSourceTransactionManager transactionManager() {
return new DataSourceTransactionManager(this.dataSource);
}
}
4. JdbcTemplateAutoConfiguration
作用:创建JdbcTemplate
@Configuration
@ConditionalOnClass({ DataSource.class, JdbcTemplate.class })
@ConditionalOnSingleCandidate(DataSource.class)
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
public class JdbcTemplateAutoConfiguration {
@Bean
@Primary
@ConditionalOnMissingBean(JdbcOperations.class)
public JdbcTemplate jdbcTemplate() {
return new JdbcTemplate(this.dataSource);
}
}
5. TransactionAutoConfiguration
作用:提供TransactionTemplate
在其加载之前要加载
JpaBaseConfiguration以及DataSourceTransactionManagerAutoConfiguration类
@AutoConfigureAfter({ JtaAutoConfiguration.class, JpaBaseConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class })
public class TransactionAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public TransactionTemplate transactionTemplate() {
return new TransactionTemplate(this.transactionManager);
}
}
时序图
看到初始化后的transactionManager和datasource