官术网_书友最值得收藏!

3.2 SpringBoot數據庫連接池加載順序剖析

HikariCP是Spring Boot 2.x版本官方宣布默認的數據庫連接池,SpringBoot對HikariCP的采納也從側面說明HikariCP在使用廣泛性、認可度、性能、穩定性等方面是經得起檢驗的,也表明HikariCP的應用前景和未來發展是一片光明。

如圖3-2所示,在SpringBoot當前最新2.x版本https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-sql.html#boot-features-connect-to-production-database的文檔中也強烈建議使用HikariCP作為默認的數據庫連接池。文檔中是這么描述的:我們更喜歡HikariCP的性能和并發性,如果HikariCP可用,我們總是選擇它;否則,如果Tomcat池DataSource可用,我們將使用它;如果HikariCP和Tomcat數據庫連接池都不可用,并且Commons DBCP2可用,我們就會使用它。當然,用戶也可以通過設置spring.datasource.type屬性來繞過上述使用順序,進而指定想要使用的數據庫連接池。

圖3-2 SpringBoot最新版本建議使用HikariCP

當然,如果這維服務使用spring-boot-starter-jdbc或者spring-boot-starter-data-jpa的starter,會自動獲得HikariCP的依賴。

其實Spring Boot 1.5.x是默認使用tomcat-jdbc作為連接池的,如下是其尋找連接池順序的規則:Tomcat pool → HikariCP → Commons DBCP → Commons DBCP2。然而在其2.x版本中,HikariCP被提升為默認的數據庫連接池,數據庫連接池的默認配置順序是HikariCP → Tomcat pool → Commons DBCP2。接下來,我們就從源碼角度給讀者詳細介紹這個規則的原理。

org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration是Spring Boot 2.0.3.Release版本中的加載數據源的核心類。在該類中,PooledDataSource-Configuration是需要重點關注的,它決定了連接池的選擇。我們可以看到圖3-2中的注解包含了HikariCP、Tomcat、DBCP2等主流連接池,選擇連接池的不同,application. properties配置也不同。

        @Configuration
        @ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
        @EnableConfigurationProperties(DataSourceProperties.class)
        @Import({ DataSourcePoolMetadataProvidersConfiguration.class,
                DataSourceInitializationConfiguration.class })
        public class DataSourceAutoConfiguration {
            @Configuration
            @Conditional(EmbeddedDatabaseCondition.class)
            @ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
            @Import(EmbeddedDataSourceConfiguration.class)
            protected static class EmbeddedDatabaseConfiguration {}
            @Configuration
            @Conditional(PooledDataSourceCondition.class)
            @ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
            @Import({ DataSourceConfiguration.Hikari.class, DataSourceConfiguration.Tomcat.
    class,
                    DataSourceConfiguration.Dbcp2.class, DataSourceConfiguration.Generic.
    class,
                    DataSourceJmxConfiguration.class })
            protected static class PooledDataSourceConfiguration {}

在上述PooledDataSourceCondition的代碼中,PooledDataSourceAvailableCondition有一段findType的代碼用來加載資源文件。

        public static Class<? extends DataSource> findType(ClassLoader classLoader){
                for (String name : DATA_SOURCE_TYPE_NAMES) {
                    try {
                        return (Class<? extends DataSource>) ClassUtils.forName(name,
    classLoader);
                    }catch (Exception ex) {
                        // Swallow and continue
                    }
                }
                return null;
            }

而這里的常量數組DATA_SOURCE_TYPE_NAMES就是關鍵,在Spring Boot 2.x的定義如下:

        private static final String[] DATA_SOURCE_TYPE_NAMES = new String[] {
                    "com.zaxxer.hikari.HikariDataSource",
                    "org.apache.tomcat.jdbc.pool.DataSource",
                    "org.apache.commons.dbcp2.BasicDataSource" };

在findType()方法中,for循環順序遍歷數組,加載到哪個類就使用哪個類的連接池,所以就是HikariCP → Tomcat pool → Commons DBCP2這樣的順序。

同理,在1.5.3.Release版本的SpringBoot的數組也是這么定義的,所以就是Tomcat Pool → HikariCP → Commons DBCP → Commons DBCP2的順序。

        private static final String[] DATA_SOURCE_TYPE_NAMES = new String[] {
                    "org.apache.tomcat.jdbc.pool.DataSource",
                    "com.zaxxer.hikari.HikariDataSource",
                    "org.apache.commons.dbcp.BasicDataSource", // deprecated
                    "org.apache.commons.dbcp2.BasicDataSource" };

所以若要在SpringBoot 1.5.3.Release版本中使用HikariCP,除了在spring.datasource. type屬性中設置以外,還有一個簡單的方法就是Maven依賴排除Tomcat-JDBC。

SpringBoot 2.0發布的時候,官方也發布了“db方面,默認引入了HikariCP,替代了之前的Tomcat-Pool作為底層的數據庫連接池。對比Tomcat-Pool, HikariCP擁有更好的性能,總而言之就是提高了db的訪問速度”這樣的版本變更信息。讀到這里讀者應該能夠清晰地理解SpringBoot在數據庫連接池選型這件事上的來龍去脈了。

主站蜘蛛池模板: 镇坪县| 青岛市| 永定县| 安国市| 巩义市| 山东省| 望奎县| 大新县| 广宗县| 太康县| 正镶白旗| 汉源县| 福建省| 巩留县| 容城县| 保定市| 贡山| 勃利县| 镇雄县| 巴林右旗| 垫江县| 石嘴山市| 邵阳市| 定日县| 和静县| 关岭| 黄山市| 池州市| 获嘉县| 龙口市| 蚌埠市| 新绛县| 曲阳县| 永寿县| 井研县| 信阳市| 安达市| 靖远县| 木兰县| 华阴市| 吉安市|