spring boot中事务功能自动配置的加载过程分析

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 接口,不同的数据访问技术的事务使用不同的接口实现。

数据库访问技术实现类
JDBCDataSourceTransactionManager
JPAJpaTransactionManager
HibernateHibernateTransactionManager

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

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值