spring boot 源码解析22-spring boot jdbc自动化配置

前言

spring boot 中关于jdbc的自动化配置如下:

  • org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
  • org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration
  • org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration–> 不解析
  • org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration–> 不解析
  • org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration

我们将依次解析DataSourceAutoConfiguration,JdbcTemplateAutoConfiguration,DataSourceTransactionManagerAutoConfiguration.下面我们开始吧

DataSourceAutoConfiguration

  1. DataSourceAutoConfiguration声明的注解如下:

    @Configuration
    @ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
    @EnableConfigurationProperties(DataSourceProperties.class)
    @Import({ Registrar.class, DataSourcePoolMetadataProvidersConfiguration.class })
    • @Configuration–> 配置类
    • @ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })–> 在当前类路径下存在DataSource.class,EmbeddedDatabaseType.class 时生效
    • @EnableConfigurationProperties(DataSourceProperties.class) –> 可以通过spring.datasource.xxx 进行配置,同时导入了EnableConfigurationPropertiesImportSelector
    • @Import({ Registrar.class, DataSourcePoolMetadataProvidersConfiguration.class })–> 导入了Registrar, DataSourcePoolMetadataProvidersConfiguration
  2. parse过程:

    1. 由于DataSourceAutoConfiguration有3个配置内部类(声明有@Configuration注解的内部类),依次会先parse其内部类:

      1. TomcatDataSourceJmxConfiguration:

        1. TomcatDataSourceJmxConfiguration 声明的注解如下:

          @ConditionalOnProperty(prefix = "spring.datasource", name = "jmx-enabled")
          @ConditionalOnClass(name = "org.apache.tomcat.jdbc.pool.DataSourceProxy")
          @Conditional(DataSourceAutoConfiguration.DataSourceAvailableCondition.class)
          @ConditionalOnMissingBean(name = "dataSourceMBean")
          • @ConditionalOnProperty(prefix = “spring.datasource”, name = “jmx-enabled”)–> 当配置有spring.datasource.jmx-enabled属性,并且其值为true时生效
          • @ConditionalOnClass(name = “org.apache.tomcat.jdbc.pool.DataSourceProxy”)–> 在当前类路径下存在org.apache.tomcat.jdbc.pool.DataSourceProxy时生效
          • @ConditionalOnMissingBean(name = “dataSourceMBean”)–> 当beanFactory中不存在id为dataSourceMBean的bean时生效
          • @Conditional(DataSourceAutoConfiguration.DataSourceAvailableCondition.class)–> 通过DataSourceAvailableCondition进行判断.代码如下:

                    public ConditionOutcome getMatchOutcome(ConditionContext context,
            AnnotatedTypeMetadata metadata) {
            ConditionMessage.Builder message = ConditionMessage
            .forCondition("DataSourceAvailable");
            // 1. 如果BeanFactory中存在DataSource类型的bean或者存在XADataSource类型的bean时返回匹配
            if (hasBean(context, DataSource.class)
            || hasBean(context, XADataSource.class)) {
            return ConditionOutcome
                .match(message.foundExactly("existing data source bean"));
            }
            // 2. 只要 pooledCondition,embeddedCondition 中任意一个满足,则返回匹配
            if (anyMatches(context, metadata, this.pooledCondition,
            this.embeddedCondition)) {
            return ConditionOutcome.match(message
                .foundExactly("existing auto-configured data source bean"));
            }
            // 3. 返回不匹配
            return ConditionOutcome
            .noMatch(message.didNotFind("any existing data source bean").atAll());
            }
            1. 如果BeanFactory中存在DataSource类型的bean或者存在XADataSource类型的bean时返回匹配
            2. 只要 pooledCondition,embeddedCondition 中任意一个满足,则返回匹配

              1. PooledDataSourceCondition 判断逻辑如下:

                1. 配置有spring.datasource.type并且其值不是false 时生效
                2. 如果在当前类路径下存在

                  • org.apache.tomcat.jdbc.pool.DataSource
                  • com.zaxxer.hikari.HikariDataSource
                  • org.apache.commons.dbcp.BasicDataSource
                  • org.apache.commons.dbcp2.BasicDataSource

                  中的任意一个时匹配.

                只要第1,2点任意一个匹配,则返回匹配

              2. embeddedCondition 判断逻辑如下:

                1. 如果存在数据库连接池则不匹配
                2. 如果当前路径下不存在H2,DERBY,HSQL时,返回不匹配,否则,返回匹配
            3. 返回不匹配

          因此,该配置类TomcatDataSourceJmxConfiguration在默认情况下是不生效的.

        2. 如果该配置生效的话,由于该类有一个被@Bean注解的方法:

          @Bean
          public Object dataSourceMBean(DataSource dataSource) {
          if (dataSource instanceof DataSourceProxy) {
          try {
              return ((DataSourceProxy) dataSource).createPool().getJmxPool();
          }
          catch (SQLException ex) {
              logger.warn("Cannot expose DataSource to JMX (could not connect)");
          }
          }
          return null;
          }
          1. 如果此时注入的是DataSourceProxy,则将其强转为DataSourceProxy后创建jmxPool
          2. 否则,返回null.
      2. PooledDataSourceConfiguration:

        1. PooledDataSourceConfiguration 注解如下:

          @Configuration
          @Conditional(PooledDataSourceCondition.class)
          @ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
          @Import({ DataSourceConfiguration.Tomcat.class, DataSourceConfiguration.Hikari.class,
          DataSourceConfiguration.Dbcp.class, DataSourceConfiguration.Dbcp2.class,
          DataSourceConfiguration.Generic.class })
          • @Configuration –> 配置类
          • @Conditional(PooledDataSourceCondition.class)–>

            1. 配置有spring.datasource.type并且其值不是false 时生效,
            2. 如果在当前类路径下存在

              • org.apache.tomcat.jdbc.pool.DataSource
              • com.zaxxer.hikari.HikariDataSource
              • org.apache.commons.dbcp.BasicDataSource
              • org.apache.commons.dbcp2.BasicDataSource

              任意一个时生效

            1,2 点任意一个匹配返回匹配

          • @ConditionalOnMissingBean({ DataSource.class, XADataSource.class })–> beanFactory中不存在DataSource,XADataSource类型的bean时生效
          • @Import({ DataSourceConfiguration.Tomcat.class, DataSourceConfiguration.Hikari.class,
            DataSourceConfiguration.Dbcp.class, DataSourceConfiguration.Dbcp2.class,
            DataSourceConfiguration.Generic.class })–> 导入了Tomcat,Hikari,Dbcp, Dbcp2的配置
        2. 由于该类没有内部类,声明@Bean方法,只有@Import注解,因此,会调用ConfigurationClassParser#processImports依次处理之:

          1. Tomcat 不是ImportSelector,ImportBeanDefinitionRegistrar的实例,因此会调用ConfigurationClassParser#processConfigurationClass 来处理.

            1. Tomcat 注解如下:

              @ConditionalOnClass(org.apache.tomcat.jdbc.pool.DataSource.class)
              @ConditionalOnProperty(name = "spring.datasource.type", havingValue = "org.apache.tomcat.jdbc.pool.DataSource", matchIfMissing = true)
              • ConditionalOnClass(org.apache.tomcat.jdbc.pool.DataSource.class)–>当前类路径下存在org.apache.tomcat.jdbc.pool.DataSource时生效
              • @ConditionalOnProperty(name = “spring.datasource.type”, havingValue = “org.apache.tomcat.jdbc.pool.DataSource”, matchIfMissing = true)–> 配置有spring.datasource.type= org.apache.tomcat.jdbc.pool.DataSource 时生效或者没有配置spring.datasource.type时,该配置类默认生效.

              * 由于,我们一般都会加入spring-boot-starter-jdbc,而该项目依赖了tomcat-jdbc,因此,该配置默认生效*

            2. Tomcat中只有一个@Bean方法,代码如下:

              @Bean
              @ConfigurationProperties(prefix = "spring.datasource.tomcat")
              public org.apache.tomcat.jdbc.pool.DataSource dataSource(
              DataSourceProperties properties) {
              org.apache.tomcat.jdbc.pool.DataSource dataSource = createDataSource(
              properties, org.apache.tomcat.jdbc.pool.DataSource.class);
              DatabaseDriver databaseDriver = DatabaseDriver
              .fromJdbcUrl(properties.determineUrl());
              String validationQuery = databaseDriver.getValidationQuery();
              if (validationQuery != null) {
              dataSource.setTestOnBorrow(true);
              dataSource.setValidationQuery(validationQuery);
              }
              return dataSource;
              }
              • @Bean –> 注册id为dataSource,类型为org.apache.tomcat.jdbc.pool.DataSource的bean
              • @ConfigurationProperties(prefix = “spring.datasource.tomcat”)–>可通过spring.datasource.tomcat.xxxx进行配置.
            3. 由于Tomcat有父类–>DataSourceConfiguration,因此会对其父类进行解析,而该父类只有Tomcat,Hikari,Dbcp,Dbcp2,Generic 这几个配置内部类,正好是在PooledDataSourceConfiguration导入的,由于后面要依次进行说明,因此这里就不在赘述了.
          2. Hikari–> 同样会调用ConfigurationClassParser#processConfigurationClass 来处理:

            1. 注解如下:

              @ConditionalOnClass(HikariDataSource.class)
              @ConditionalOnProperty(name = "spring.datasource.type", havingValue = "com.zaxxer.hikari.HikariDataSource", matchIfMissing = true)
              • @ConditionalOnClass(HikariDataSource.class)–> 在当前类路径下存在HikariDataSource.class时生效
              • @ConditionalOnProperty(name = “spring.datasource.type”, havingValue = “com.zaxxer.hikari.HikariDataSource”, matchIfMissing = true)–>配置有spring.datasource.type=com.zaxxer.hikari.HikariDataSource 时生效或者没有配置spring.datasource.type时,该配置类默认生效.

              由于默认情况下,没有依赖Hikari相关的jar包,因此该配置不会生效

            2. 如果生效的话,则会激活配置,该配置类只有一个@Bean方法,如下:

              @Bean
              @ConfigurationProperties(prefix = "spring.datasource.hikari")
              public HikariDataSource dataSource(DataSourceProperties properties) {
              return createDataSource(properties, HikariDataSource.class);
              }
              • @Bean –> 注册一个id为dataSource,类型为HikariDataSource的bean
              • @ConfigurationProperties(prefix = “spring.datasource.hikari”)–> 可通过 spring.datasource.hikari.xxx 进行配置
          3. Dbcp,Dbcp2,Generic 这3个内部类的处理和Hikari一样,都是默认不生效的,如果生效的化,会注册1个id为dataSource,类型为相应数据库连接池类型的bean,节约篇幅,这里就不赘述了.

      3. EmbeddedDatabaseConfiguration

        1. EmbeddedDatabaseConfiguration注解如下:

          @Configuration
          @Conditional(EmbeddedDatabaseCondition.class)
          @ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
          @Import(EmbeddedDataSourceConfiguration.class)
          • @Configuration–> 配置类
          • @Conditional(EmbeddedDatabaseCondition.class) –> 当前路径下不存在H2,DERBY,HSQL时,返回不匹配,否则,返回匹配
          • @ConditionalOnMissingBean({ DataSource.class, XADataSource.class })–> 当beanFactory中不存在DataSource,XADataSource类型的bean时生效
          • @Import(EmbeddedDataSourceConfiguration.class) –> 导入了EmbeddedDataSourceConfiguration相关的配置.

          由于默认情况下是不满足@Conditional(EmbeddedDatabaseCondition.class)的条件,因此该配置不会被解析,因此也就不解析了这里.

    2. 处理完DataSourceAutoConfiguration的配置内部类之后,由于DataSourceAutoConfiguration有如下注解:

      @EnableConfigurationProperties(DataSourceProperties.class)
      @Import({ Registrar.class, DataSourcePoolMetadataProvidersConfiguration.class })

      因此会执行ConfigurationClassParser#processImports

      1. @EnableConfigurationProperties(DataSourceProperties.class) –> 导入了EnableConfigurationPropertiesImportSelector,又由于该类是ImportSelector的实现,因此会调用其selectImports方法,将返回的ConfigurationPropertiesBeanRegistrar,ConfigurationPropertiesBindingPostProcessorRegistrar在次调用processImports进行处理.(关于@EnableConfigurationProperties的解析,我们已经见过很多次了)

        ConfigurationPropertiesBeanRegistrar, ConfigurationPropertiesBindingPostProcessorRegistrar由于都是ImportBeanDefinitionRegistrar的实例,因此会将其加入到DataSourceAutoConfiguration所对应的ConfigurationClass中的importBeanDefinitionRegistrars

      2. DataSourceInitializerPostProcessor$Registrar 由于也是ImportBeanDefinitionRegistrar的实例,因此会将其加入到DataSourceAutoConfiguration所对应的ConfigurationClass中的importBeanDefinitionRegistrars
      3. DataSourcePoolMetadataProvidersConfiguration,不是ImportSelector,ImportBeanDefinitionRegistrar的实例,因此会将其按照一个配置类来进行解析:

        1. DataSourcePoolMetadataProvidersConfiguration中只声明了4个配置类,其中默认生效的是TomcatDataSourcePoolMetadataProviderConfiguration.而在TomcatDataSourcePoolMetadataProviderConfiguration中声明了一个@Bean方法.如下:

          @Bean
          public DataSourcePoolMetadataProvider tomcatPoolDataSourceMetadataProvider() {
          return new DataSourcePoolMetadataProvider() {
          @Override
          public DataSourcePoolMetadata getDataSourcePoolMetadata(
                  DataSource dataSource) {
              if (dataSource instanceof org.apache.tomcat.jdbc.pool.DataSource) {
                  return new TomcatDataSourcePoolMetadata(
                          (org.apache.tomcat.jdbc.pool.DataSource) dataSource);
              }
              return null;
          }
          };
          }

          注册id为tomcatPoolDataSourceMetadataProvider,类型为DataSourcePoolMetadataProvider的bean

        2. DataSourcePoolMetadataProvidersConfiguration 中各内部类下面列出的一个表格:

          类名激活条件beanid
          TomcatDataSourcePoolMetadataProviderConfiguration在类路径下存在org.apache.tomcat. jdbc.pool. DataSourceid为tomcatPoolDataSourceMetadataProvider
          HikariPoolDataSourceMetadataProviderConfiguration在类路径下存在HikariDataSourcehikariPoolDataSourceMetadataProvider
          CommonsDbcpPoolDataSourceMetadataProviderConfiguration在类路径下存在org.apache.commons.dbcp.BasicDataSourcecommonsDbcpPoolDataSourceMetadataProvider
          CommonsDbcp2PoolDataSourceMetadataProviderConfiguration在类路径下存在BasicDataSourcecommonsDbcp2PoolDataSourceMetadataProvider

          ps: 它们注册的bean类型都是DataSourcePoolMetadataProvider

    3. 处理完@Import后,DataSourceAutoConfiguration只有1个@Bean方法,如下:

      @Bean
      @ConditionalOnMissingBean
      public DataSourceInitializer dataSourceInitializer(DataSourceProperties properties,
          ApplicationContext applicationContext) {
      return new DataSourceInitializer(properties, applicationContext);
      }
      
      • @Bean –> 注册id为dataSourceInitializer,类型为DataSourceInitializer的bean
      • @ConditionalOnMissingBean–> 当BeanFactory中不存在DataSourceInitializer类型的bean时生效.
  3. 加载(ConfigurationClassBeanDefinitionReader#loadBeanDefinitions):

    1. DataSourceConfiguration$Tomcat:

      1. 由于是被PooledDataSourceConfiguration导入的,因此会执行ConfigurationClassBeanDefinitionReader#registerBeanDefinitionForImportedConfigurationClass进行注册,id为tomcat.

      2. 由于该类声明了1个@Bean方法,因此会调用ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForBeanMethod 进行注册

    2. PooledDataSourceConfiguration:

      1. 由于是被DataSourceAutoConfiguration导入的,因此会进行注册,id为pooledDataSourceConfiguration
    3. TomcatDataSourcePoolMetadataProviderConfiguration:

      1. 由于是被DataSourcePoolMetadataProvidersConfiguration导入的(DataSourceAutoConfiguration通过@Import 导入DataSourcePoolMetadataProvidersConfiguration,而TomcatDataSourcePoolMetadataProviderConfiguration是DataSourcePoolMetadataProvidersConfiguration的配置内部类),因此会进行注册,id为tomcatDataSourcePoolMetadataProviderConfiguration
      2. 由于该类声明了@Bean方法(tomcatPoolDataSourceMetadataProvider方法),因此会调用ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForBeanMethod 进行注册
    4. DataSourcePoolMetadataProvidersConfiguration:

      1. 由于是被DataSourceAutoConfiguration导入的(通过@Import),因此会进行注册,id为dataSourcePoolMetadataProvidersConfiguration
    5. DataSourceAutoConfiguration:

      1. 由于是被启动类导入的,因此会进行注册,id为dataSourceAutoConfiguration
      2. 声明了@Bean方法(dataSourceInitializer),因此会调用ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForBeanMethod 进行注册
      3. 由于DataSourceAutoConfiguration对应的ConfigurationClass中importBeanDefinitionRegistrars不为空,因此会调用ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsFromRegistrars,在该方法中会遍历importBeanDefinitionRegistrars,依次调用其registerBeanDefinitions方法.

        1. ConfigurationPropertiesBeanRegistrar –> 注册了一个id为spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties,类型为DataSourceProperties的bean
        2. ConfigurationPropertiesBindingPostProcessorRegistrar–>如果beanFactory中不存在id为org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor的bean,则注册如下bean:

          • id为org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor,类型为ConfigurationPropertiesBindingPostProcessor
          • id为org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.store,类型为ConfigurationPropertiesBindingPostProcessor
        3. DataSourceInitializerPostProcessor$Registrar,代码如下:

          public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
          BeanDefinitionRegistry registry) {
          if (!registry.containsBeanDefinition(BEAN_NAME)) {
          GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
          beanDefinition.setBeanClass(DataSourceInitializerPostProcessor.class);
          beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
          // We don't need this one to be post processed otherwise it can cause a
          // cascade of bean instantiation that we would rather avoid.
          beanDefinition.setSynthetic(true);
          registry.registerBeanDefinition(BEAN_NAME, beanDefinition);
          }
          }

          如果BeanDefinitionRegistry中不存在id为dataSourceInitializerPostProcessor的bean,则注册一个id为dataSourceInitializerPostProcessor,类型为DataSourceInitializerPostProcessor,角色为内部使用的bean.并将其设置为synthetic,这是因为如果不这样做,就会导致一系列的bean初始化.

JdbcTemplateAutoConfiguration

  1. JdbcTemplateAutoConfiguration注解如下:

    @Configuration
    @ConditionalOnClass({ DataSource.class, JdbcTemplate.class })
    @ConditionalOnSingleCandidate(DataSource.class)
    @AutoConfigureAfter(DataSourceAutoConfiguration.class)
    • @Configuration –> 配置类
    • @ConditionalOnClass({ DataSource.class, JdbcTemplate.class }) –> 在当前类路径下存在DataSource.class,JdbcTemplate.class 时该配置生效
    • @ConditionalOnSingleCandidate(DataSource.class)–> 当beanFactory中存在DataSource类型的bean并且当存在多个DataSource时,声明为@Primary的DataSource存在时生效
    • @AutoConfigureAfter(DataSourceAutoConfiguration.class) –> 在DataSourceAutoConfiguration 之后进行配置,这样才能注入DataSource
  2. JdbcTemplateAutoConfiguration 比较简单,没有内部类,只有两个被@bean注解的方法:

    1. jdbcTemplate方法,注册了一个id为jdbcTemplate,类型为JdbcTemplate的bean,代码如下:

      @Bean
      @Primary
      @ConditionalOnMissingBean(JdbcOperations.class)
      public JdbcTemplate jdbcTemplate() {
          return new JdbcTemplate(this.dataSource);
      }
      • @Primary –> 当BeanFactory中有多个JdbcTemplate时,该配置的JdbcTemplate 会在自动装配(byType)时自动注入
      • @ConditionalOnMissingBean(JdbcOperations.class)–> 当BeanFactory中没有JdbcOperations类型的bean时该bean进行注册
    2. namedParameterJdbcTemplate方法,代码如下:

      @Bean
      @Primary
      @ConditionalOnMissingBean(NamedParameterJdbcOperations.class)
      public NamedParameterJdbcTemplate namedParameterJdbcTemplate() {
      return new NamedParameterJdbcTemplate(this.dataSource);
      }
      • @Bean –> 注册一个id为namedParameterJdbcTemplate,类型为NamedParameterJdbcTemplate的bean
      • @Primary–> 当BeanFactory中有多个NamedParameterJdbcTemplate时,该配置的NamedParameterJdbcTemplate 会在自动装配(byType)时自动注入
      • @ConditionalOnMissingBean(NamedParameterJdbcOperations.class)–>当BeanFactory中没有NamedParameterJdbcTemplate类型的bean时该bean进行注册

DataSourceTransactionManagerAutoConfiguration

  1. DataSourceTransactionManagerAutoConfiguration 注解如下:

    @Configuration
    @ConditionalOnClass({ JdbcTemplate.class, PlatformTransactionManager.class })
    @AutoConfigureOrder(Ordered.LOWEST_PRECEDENCE)
    @EnableConfigurationProperties(DataSourceProperties.class)
    • @Configuration –> 配置类
    • @ConditionalOnClass({ JdbcTemplate.class, PlatformTransactionManager.class })–> 在当前类路径下存在JdbcTemplate.class, PlatformTransactionManager.class时生效
    • @AutoConfigureOrder(Ordered.LOWEST_PRECEDENCE) –> 自动配置优先级为Integer.MAX_VALUE.
    • @EnableConfigurationProperties(DataSourceProperties.class)–> 可通过spring.datasource.xxx进行配置
  2. parse过程:

    1. DataSourceTransactionManagerAutoConfiguration 由于有内部类,因此会先parse其内部类–> DataSourceTransactionManagerConfiguration.

      1. DataSourceTransactionManagerConfiguration有如下注解:

        @Configuration
        @ConditionalOnSingleCandidate(DataSource.class)
        • @Configuration –> 配置类
        • @ConditionalOnSingleCandidate(DataSource.class)–>当beanFactory中存在DataSource类型的bean并且当存在多个DataSource时,声明为@Primary的DataSource存在时生效
      2. DataSourceTransactionManagerConfiguration只有一个被@Bean注解的方法:

        @Bean
        @ConditionalOnMissingBean(PlatformTransactionManager.class)
        public DataSourceTransactionManager transactionManager(
            DataSourceProperties properties) {
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(
                this.dataSource);
        if (this.transactionManagerCustomizers != null) {
            this.transactionManagerCustomizers.customize(transactionManager);
        }
        return transactionManager;
        }
        • @Bean–> 注册一个id为transactionManager,类型为DataSourceTransactionManager的bean
        • @ConditionalOnMissingBean(PlatformTransactionManager.class) –> 当beanFactory中不存在DataSourceTransactionManager类型的bean时生效
    2. 由于@EnableConfigurationProperties(DataSourceProperties.class)其元注解中通过@Import(EnableConfigurationPropertiesImportSelector.class) 导入了EnableConfigurationPropertiesImportSelector.因此会在ConfigurationClassParser#processImports方法依次处理EnableConfigurationPropertiesImportSelector#selectImports的返回值–>ConfigurationPropertiesBeanRegistrar.class,ConfigurationPropertiesBindingPostProcessorRegistrar.class。

      1. 由于ConfigurationPropertiesBeanRegistrar 是ImportBeanDefinitionRegistrar的实例,因此会实例化后加入到DataSourceTransactionManagerAutoConfiguration对应的ConfigurationClass中的importBeanDefinitionRegistrars
      2. ConfigurationPropertiesBindingPostProcessorRegistrar 同样是ImportBeanDefinitionRegistrar的实例.因此也会同时加入到importBeanDefinitionRegistrars.
  3. 加载(ConfigurationClassBeanDefinitionReader#loadBeanDefinitions):

    1. DataSourceTransactionManagerConfiguration:

      1. 由于该配置是被DataSourceTransactionManagerAutoConfiguration导入的,因此会执行ConfigurationClassBeanDefinitionReader#registerBeanDefinitionForImportedConfigurationClass方法进行注册,id为dataSourceTransactionManagerConfiguration.

        由于DataSourceTransactionManagerAutoConfiguration有一个被@bean注解的方法–>transactionManager.因此会调用ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForBeanMethod进行注册

    2. DataSourceTransactionManagerAutoConfiguration:

      1. DataSourceTransactionManagerAutoConfiguration 是被spring boot 启动类导入的 因此会执行ConfigurationClassBeanDefinitionReader#registerBeanDefinitionForImportedConfigurationClass方法进行注册,id为dataSourceTransactionManagerAutoConfiguration
      2. 在解析过程中,由于向DataSourceTransactionManagerAutoConfiguration对应的ConfigurationClass中添加了2个importBeanDefinitionRegistrars,因此会调用ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsFromRegistrars

        1. ConfigurationPropertiesBeanRegistrar–>如果beanFactory中不存在id为spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties 的bean,则进行注册,类型为DataSourceProperties
        2. ConfigurationPropertiesBindingPostProcessorRegistrar–> 如果beanFactory中不存在id为org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor的bean,则注册如下bean:

          • id为org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor,类型为ConfigurationPropertiesBindingPostProcessor
          • id为org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.store,类型为ConfigurationPropertiesBindingPostProcessor
    原文作者:Spring Boot
    原文地址: https://blog.csdn.net/qq_26000415/article/details/79027165
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞