其他分享
首页 > 其他分享> > spring全家桶学习-springboot 默认使用 hikaricp

spring全家桶学习-springboot 默认使用 hikaricp

作者:互联网

根据springboot 自动装配的特性来分析 为什么 springboot 默认使用 hikaricp 作为数据库连接池?

 

通过 SpringBootApplication 注解可以看到一个关键的注解 就是 EnableAutoConfiguration; 

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
.... 省略其他
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class) // 核心点
public @interface EnableAutoConfiguration {
...
}

其通过使用 Import注解往当前容器引入AutoConfigurationImportSelector作为组件, 其通过 org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#selectImports 方法来 加载 spring-boot-auto-configure jar中的 META-INF/spring.factories 文件中关于 EnableAutoConfiguration属性中的相关属性值,通过加载解析相关的 **AutoConfiguration类 来实现自动装配的目的;

 

以 DataSourceAutoConfiguration 为例

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@ConditionalOnMissingBean(type = "io.r2dbc.spi.ConnectionFactory")
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({ DataSourcePoolMetadataProvidersConfiguration.class, DataSourceInitializationConfiguration.class })
public class DataSourceAutoConfiguration {

    @Configuration(proxyBeanMethods = false)
    @Conditional(EmbeddedDatabaseCondition.class)
    @ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
    @Import(EmbeddedDataSourceConfiguration.class)
    protected static class EmbeddedDatabaseConfiguration {

    }

    @Configuration(proxyBeanMethods = false) // 声明当前类作为配置类装载到spring 容器中
    @Conditional(PooledDataSourceCondition.class) // 限制要求只有在满足当前注解中属性值(PooledDataSourceCondition)判断通过的情况下才允许初始化当前bean
    @ConditionalOnMissingBean({ DataSource.class, XADataSource.class }) // 如果容器中不存在当前bean(DataSource / XADataSource),则会执行当前注解标记的类或方法来实现bean的初始化
    @Import({ DataSourceConfiguration.Hikari.class, DataSourceConfiguration.Tomcat.class,
            DataSourceConfiguration.Dbcp2.class, DataSourceConfiguration.OracleUcp.class,
            DataSourceConfiguration.Generic.class, DataSourceJmxConfiguration.class })// 关于Import的作用为给容器注入一个组件,支持通过数组配置多个类,表示将所有存在的bean引入当前配置
    protected static class PooledDataSourceConfiguration { // 连接池相关配置

    }
... 省略代码
}

在这里其核心主要使用以下注解

  1. Conditional 条件判断限制bean的生成
  2. ConditionalOnMissingBean 判断需要的bean是否存在,当bean在容器中不存在的情况下,会注解中配置的bean的类型进行初始化操作
  3. Import 为当前容器引入对应的组件(bean)

 

关于 Import 中的 "DataSourceConfiguration.Hikari.class" 

    /**
     * Hikari DataSource configuration.
     */
    @Configuration(proxyBeanMethods = false) // 表示当前也为配置类
    @ConditionalOnClass(HikariDataSource.class)// 条件判断要求 HikariDataSource 类必须存在于当前classPath下,由于spring-boot-stater-jdbc jar中默认引入了 HikariCP jar,且HikariCPDataSource类在当前jar中存在
    @ConditionalOnMissingBean(DataSource.class) // 判断如果当前 Datasource bean 在spring 容器中不存在,则通过当前配置类执行bean初始化操作
    @ConditionalOnProperty(name = "spring.datasource.type", havingValue = "com.zaxxer.hikari.HikariDataSource",
            matchIfMissing = true) // 判断属性是否存在,通过设置matchIfMissing = true 表示即使在当前属性条件不满足的情况下也会执行后续的操作
    static class Hikari {

        @Bean // 通过方法生成当前类作为springbean
        @ConfigurationProperties(prefix = "spring.datasource.hikari") // 解析配置文件中指定前缀的属性值,并注入到当前参数中
        HikariDataSource dataSource(DataSourceProperties properties) {
            HikariDataSource dataSource = createDataSource(properties, HikariDataSource.class);//创建 HikariDataSource实例并返回,其会被加载到spring 容器中作为spring bean 存在
            if (StringUtils.hasText(properties.getName())) {
                dataSource.setPoolName(properties.getName());
            }
            return dataSource;
        }

    }

 

回答开篇的问题,为什么SpringBoot 2.0 中在不配置任何属性情况下能自动获取到Hikaricp作为默认数据库连接池? 

由于HikariDataSource 当前类 属于 com.zaxxer.HikariCP jar,  从springboot 2.0 开始 spring-boot-starter-jdbc 默认引入了HikariCP jar(参考以下xml文件);

因此在不额外引入其他相关数据库连接池依赖jar 的情况下,会默认使用 hikaricp作为默认数据库连接池; 

需要注意的一点在于,在spring-boot 2.0中如果需要使用其他的支持自动装配的数据库连接池,最好排除(exclude) HikariCP jar;

由于自动装配的优先级最低,且一般要求只有在容器中不存在指定bean的情况下才会进行自动配置;

如果通过自定义配置类来设置相关的DataSource Bean,则自动装配实际并不会被执行;但还是建议在SpringBootApplication注解的 exclude 属性中排除掉相关的 *AutoConfiguration类

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <!-- This module was also published with a richer model, Gradle metadata,  -->
  <!-- which should be used instead. Do not delete the following line which  -->
  <!-- is to indicate to Gradle or any Gradle module metadata file consumer  -->
  <!-- that they should prefer consuming it instead. -->
  <!-- do_not_remove: published-with-gradle-metadata -->
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-jdbc</artifactId>
  <version>2.4.1</version>
  <name>spring-boot-starter-jdbc</name>
  <description>Starter for using JDBC with the HikariCP connection pool</description>
  <url>https://spring.io/projects/spring-boot</url>
  <organization>
    <name>Pivotal Software, Inc.</name>
    <url>https://spring.io</url>
  </organization>
  <licenses>
    <license>
      <name>Apache License, Version 2.0</name>
      <url>https://www.apache.org/licenses/LICENSE-2.0</url>
    </license>
  </licenses>
  <developers>
    <developer>
      <name>Pivotal</name>
      <email>info@pivotal.io</email>
      <organization>Pivotal Software, Inc.</organization>
      <organizationUrl>https://www.spring.io</organizationUrl>
    </developer>
  </developers>
  <scm>
    <connection>scm:git:git://github.com/spring-projects/spring-boot.git</connection>
    <developerConnection>scm:git:ssh://git@github.com/spring-projects/spring-boot.git</developerConnection>
    <url>https://github.com/spring-projects/spring-boot</url>
  </scm>
  <issueManagement>
    <system>GitHub</system>
    <url>https://github.com/spring-projects/spring-boot/issues</url>
  </issueManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
      <version>2.4.1</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>com.zaxxer</groupId>
      <artifactId>HikariCP</artifactId>
      <version>3.4.5</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.3.2</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>
</project>

 

标签:springboot,hikaricp,spring,boot,jar,bean,Import,class
来源: https://www.cnblogs.com/xingguoblog/p/14136726.html