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

扫码关注公众号:Java 技术驿站

发送:vip
将链接复制到本浏览器,永久解锁本站全部文章

【公众号:Java 技术驿站】 【加作者微信交流技术,拉技术群】

前言

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.DataSource id为tomcatPoolDataSourceMetadataProvider
          HikariPoolDataSourceMetadataProviderConfiguration 在类路径下存在HikariDataSource hikariPoolDataSourceMetadataProvider
          CommonsDbcpPoolDataSourceMetadataProviderConfiguration 在类路径下存在org.apache.commons.dbcp.BasicDataSource commonsDbcpPoolDataSourceMetadataProvider
          CommonsDbcp2PoolDataSourceMetadataProviderConfiguration 在类路径下存在BasicDataSource commonsDbcp2PoolDataSourceMetadataProvider

          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

来源:[]()

赞(0) 打赏
版权归原创作者所有,任何形式的转载请联系博主:daming_90:Java 技术驿站 » spring boot 源码解析22-spring boot jdbc自动化配置

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏