在實際的應用開發中,與數據庫交互通常使用數據庫連接池來重用Connection對象,減少資源消耗。
Spring Boot 的數據源是自動配置的。在 Spring Boot 2.2.1 版本中,有幾種數據源配置可選,它們按照 HikariCP -> Tomcat -> DBCP2
優先順序來選擇最后實際使用哪個數據庫連接池。
配置
在 Spring Boot 的自動化配置中,對于數據源的配置可以分為核心配置和數據源庫接池配置。
核心配置
核心配置是以 spring.datasource.*
形式開始,主要是配置數據庫的信息。本文以 MySQL
為例,先引入依賴:
<dependency>
????<groupId>org.springframework.bootgroupId>??
????<artifactId>spring-boot-starter-jdbcartifactId>
dependency>
<dependency>
????<groupId>mysqlgroupId>
????<artifactId>mysql-connector-javaartifactId>
????<scope>runtimescope>
dependency>
然后在 application.properties
中配置如下信息:
# 驅動
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 數據庫地址
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxx?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false
# 數據庫用戶名
spring.datasource.username=xxx
# 數據庫密碼
spring.datasource.password=xxx
還有其它的關于數據源的配置:
spring.datasource.continue-on-error= # 默認 false
spring.datasource.data= # 指定DML腳本
spring.datasource.data-password=
spring.datasource.data-username=
spring.datasource.generate-unique-name= # 默認 true
spring.datasource.initialization-mode= # 默認 embedded
spring.datasource.jndi-name=
spring.datasource.name=
spring.datasource.platform= # 默認 all
spring.datasource.schema-password=
spring.datasource.schema-username=
spring.datasource.separator=
spring.datasource.sql-script-encoding=
spring.datasource.xa.data-source-class-name= ????????# 指定數據源的全限定名
spring.datasource.xa.properties.*=
數據源連接池配置
數據源連接池配置是以 spring.datasource..*
形式開始,主要是配置數據庫連接池的一些信息。
在 application.properties
中通過配置spring.datasource.type
可以指定數據源。而 Spring Boot 提供的幾種數據源可以忽略該配置。
下面介紹一下 Spring Boot 提供的幾種數據源配置。
HikariCP
HikariCP 號稱是目前世界上最快的連接池,在 pom.xml
依賴引入:
<dependency>
????<groupId>com.zaxxergroupId>
????<artifactId>HikariCPartifactId>
????<version>3.4.1version>
dependency>
而 Spring Boot 2.2.1 框架中默認推薦使用,而項目中引入的 spring-boot-starter-jdbc
依賴來操縱數據庫,就已經包括 HikariCP 連接池的依賴。我們經常用到的mybatis-spring-boot-starter
和 spring-boot-starter-data-jpa
兩個操縱數據庫的框架也依賴了 spring-boot-starter-jdbc
。
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
該配置會強制指定Hikari
連接池。
下面就開始在 application.properties
配置文件中配置HikariCP
連接池的信息并綁定到HikariDataSource
中,如果不配置,Spring Boot 會使用默認配置信息。HikariCP
的配置信息以 spring.datasource.hikari
開頭。
spring.datasource.hikari.allow-pool-suspension= # 控制池是否可以通過JMX暫停和恢復 默認 false
spring.datasource.hikari.auto-commit= # 是否自動提交事務。默認true
spring.datasource.hikari.catalog= # 為支持catalog概念的數據庫設置默認 catalog 默認 driver default
spring.datasource.hikari.connection-init-sql= # 該屬性設置一個SQL語句,在將每個新連接創建后,將其添加到池中之前執行該語句。默認 null
spring.datasource.hikari.connection-test-query= # 連接池每分配一條連接前執行的查詢語句(如SELECT 1),以驗證該連接是否是有效的。如果你的驅動支持JDBC4,HikariCP強烈建議我們不要設置此屬性。默認null
spring.datasource.hikari.connection-timeout= # 鏈接超時時間(毫秒),如果在沒有連接可用的情況下等待超過此時間,則拋出SQLException。默認30000(30秒)
spring.datasource.hikari.data-source-class-name= # JDBC驅動程序提供的DataSource類的名稱,如果使用了`jdbc-url`則不需要此屬性。默認 null
spring.datasource.hikari.data-source-j-n-d-i=
spring.datasource.hikari.data-source-properties=
spring.datasource.hikari.driver-class-name= # HikariCP將嘗試通過僅基于 jdbcUrl 的 DriverManager 解析驅動程序,但對于一些較舊的驅動程序,還必須指定 driverClassName。默認 null
spring.datasource.hikari.exception-override-class-name=
spring.datasource.hikari.health-check-properties=
spring.datasource.hikari.health-check-registry= # 該屬性允許您指定池使用的 Codahale / Dropwizard HealthCheckRegistry 的實例來報告當前健康信息 默認 null
spring.datasource.hikari.idle-timeout= # 空閑超時時間(毫秒),只有在`minimum-idlespring.datasource.hikari.initialization-fail-timeout= ????????# 如果池無法成功初始化連接,則此屬性控制池是否將 fail fast 默認 1
spring.datasource.hikari.isolate-internal-queries= # 是否在其自己的事務中隔離內部池查詢,例如連接活動測試 默認 false
spring.datasource.hikari.jdbc-url= # 數據庫鏈接地址
spring.datasource.hikari.leak-detection-threshold= # 記錄消息之前連接可能離開池的時間量,表示可能的連接泄露。默認 0
spring.datasource.hikari.login-timeout=
spring.datasource.hikari.max-lifetime= # 連接池中連接的最長聲明周期(毫秒)。數值0表示不限制。默認1800000(30分鐘)
spring.datasource.hikari.maximum-pool-size= # 連接池中可同時連接的最大連接數,當池中沒有空閑連接可用時,就會阻塞直到超出`connection-timeout`設定的值。默認10
spring.datasource.hikari.metric-registry= # 該屬性允許您指定一個 Codahale / Dropwizard MetricRegistry 的實例,供池使用以記錄各種指標 默認 null
spring.datasource.hikari.metrics-tracker-factory=
spring.datasource.hikari.minimum-idle= # 最小空閑連接數,HikariCP建議我們不要設置此值,而是充當固定大小的連接池。默認10
spring.datasource.hikari.password= # 數據庫密碼,如果使用了`jdbc-url`則需要此屬性
spring.datasource.hikari.pool-name= # 連接池名稱,主要用于顯示在日志記錄和JMX管理控制臺中。默認auto-generated
spring.datasource.hikari.read-only= # 從池中獲取的連接是否默認處于只讀模式 默認 false
spring.datasource.hikari.register-mbeans= # 是否注冊JMX管理Bean(MBeans) 默認 false
spring.datasource.hikari.scheduled-executor= # 此屬性允許您設置將用于各種內部計劃任務的 java.util.concurrent.ScheduledExecutorService 實例 默認 null
spring.datasource.hikari.schema= # 該屬性為支持模式概念的數據庫設置默認模式 默認 driver default
spring.datasource.hikari.transaction-isolation= # 控制從池返回的連接的默認事務隔離級別。默認 null
spring.datasource.hikari.username= # 數據庫賬戶,如果使用了`jdbc-url`則需要此屬性
spring.datasource.hikari.validation-timeout= # 直接將被測試活動的最大時間量。默認 5000
tomcat-jdbc
tomcat-jdbc
是commons-dbcp
連接池的一種替換或備選方案。在 pom.xml
中引入 tomcat-jdbc
依賴:
<dependency>
????<groupId>org.apache.tomcatgroupId>
????<artifactId>tomcat-jdbcartifactId>
????<version>9.0.27version>
dependency>
下面的配置會強制指定 tomcat-jdbc
連接池。
spring.datasource.type=org.apache.tomcat.jdbc.pool.DataSource
下面就開始在 application.properties
配置文件中配置tomcat-jdbc
連接池的信息并綁定到org.apache.tomcat.jdbc.pool.DataSource
中,如果不配置,Spring Boot 會使用默認配置信息。tomcat-jdbc
的配置信息以 spring.datasource.tomcat
開頭。
spring.datasource.tomcat.abandon-when-percentage-full= # 除非使用中連接的數目超過該屬性定義的百分比,否則不會關閉并報告已廢棄的連接(因為超時)。取值范圍 0~100。默認0,意味著只要達到 remove-abandoned-timeout,就應關閉連接。
spring.datasource.tomcat.access-to-underlying-connection-allowed= # 沒有用到的屬性。可以在歸入池內的連接上調用unwrap來訪問。
spring.datasource.tomcat.alternate-username-allowed= # 默認false
spring.datasource.tomcat.commit-on-return= # 如果`auto-commit=false`,那么當連接返回池中時,池會在連接上調用提交方法,從而完成事務;如果`rollback-on-return=true`,則忽略該屬性。默認false
spring.datasource.tomcat.connection-properties= # 在建立新連接時,發送給JDBC驅動的連接屬性。字符串格式必須為 `[propertyName=property;]*`。user與password屬性會顯示傳入,這里不需要包括它們。默認null
spring.datasource.tomcat.data-source= # (javax.sql.DataSource)將數據源注入連接池,從而使池利用數據源來獲取連接,而不是利用`java.sql.Driver`接口來建立連接。它非常適用于使用數據源(而非連接字符串)來池化XA連接或者已建立的連接時。默認null
spring.datasource.tomcat.data-source-j-n-d-i= # 在JNDI中查找的數據源的JNDI名稱,隨后將用于建立數據庫連接。默認null
spring.datasource.tomcat.db-properties=
spring.datasource.tomcat.default-auto-commit= # 連接池中創建的連接默認是否自動提交狀態。未設置則默認采用JDBC驅動的缺省值
spring.datasource.tomcat.default-catalog= # 連接池中穿件的連接的默認catalog
spring.datasource.tomcat.default-read-only= # 連接池中創建的連接。默認只讀模式
spring.datasource.tomcat.default-transaction-isolation= # 連接池創建的連接的默認事務隔離狀態。取值范圍是`NONE/READ_COMMITTED/READ_UNCOMMITTED/REPEATABLE_READ/SERIALIZABLE`。默認為JDBC驅動
spring.datasource.tomcat.driver-class-name= # 使用的JDBC驅動的完全限定名。該驅動必須能從域tomcat-jdbc.jar同樣的類加載器訪問
spring.datasource.tomcat.fair-queue= # 對空閑連接列表將采用`org.apache.tomcat.jdbc.pool.FairBlockingQueue`實現。如果想使用異步連接獲取功能,必須使用該標記。設置該標記可保證線程能夠按照連接抵達順序來接收連接。。默認true
spring.datasource.tomcat.ignore-exception-on-pre-load= # 在初始化池時,是否忽略連接創建錯誤。取值為true時表示忽略;設為false時,拋出異常,從而宣告池初始化失敗。默認false
spring.datasource.tomcat.init-s-q-l= # 當連接第一次創建時,運行的自定義查詢。默認null
spring.datasource.tomcat.initial-size= # 連接器啟動時創建的初始連接數量。默認10
spring.datasource.tomcat.jdbc-interceptors= # 定義攔截器,并且插入到 java.sql.Connection 對象的操作隊列中。預定義的攔截器有`ConnectionState`記錄自動提交、只讀、catalog以及事務隔離級別等狀態,`StatementFinalizer`記錄打開的語句,并當連接返回池后關閉它們
spring.datasource.tomcat.jmx-enabled= # 是否利用JMX注冊連接池。默認true
spring.datasource.tomcat.log-abandoned= # 標志能夠針對丟棄連接的應用代碼,進行堆棧跟蹤記錄。由于生成堆棧跟蹤,對廢棄連接的日期記錄會增加每一個借取連接的開銷。默認false
spring.datasource.tomcat.log-validation-errors= # 設為true時,能將驗證階段的錯誤記錄到日志文件中,錯誤會被記錄為SEVERE。考慮向后兼容性,默認false
spring.datasource.tomcat.login-timeout=
spring.datasource.tomcat.max-active= # 連接池同一時間可分配的最大活躍連接數。默認 100
spring.datasource.tomcat.max-age= # 連接保持時間(毫秒)。當連接要返回池中時,連接池會檢查是否達到 `now - time-when-connected > max-age`的條件,如果條件達成,則關閉該連接,不再將其返回池中。默認0,意味著連接將保持開放狀態,在將連接返回池中時,不會執行任何年齡檢查。
spring.datasource.tomcat.max-idle= # 始終保留在池中的最大連接數,如果啟用,將周期性檢查閑置連接,留滯時間超過minEvictableldleTimeMillis的連接被釋放。默認 100
spring.datasource.tomcat.max-wait= # 拋出異常之前的最長等待時間。默認30000毫秒(30秒)
spring.datasource.tomcat.min-evictable-idle-time-millis= # 連接在池中保持空閑而不被回收的最小時間(毫秒)。默認60000(60秒)
spring.datasource.tomcat.min-idle= # 始終保留在池中的最小連接數。池中的連接數量低于此值會創建新的連接,如果連接驗證失敗會縮減此值。默認100
spring.datasource.tomcat.name=
spring.datasource.tomcat.num-tests-per-eviction-run= # Tomcat JDBC連接池沒有用到這個屬性
spring.datasource.tomcat.password= # 建立JDBC連接的密碼
spring.datasource.tomcat.propagate-interrupt-state= # 傳播已中斷的線程(還沒有清除中斷狀態)的中斷狀態。考慮夏侯兼容性,默認false
spring.datasource.tomcat.remove-abandoned= # 該值為標志值,表示如果連接時間超出了 remove-abandoned-timeout 的限制且被設置為true,連接會被認為是廢棄連接,應予以清除。若應用關閉連接失敗時,該值設為true能夠恢復該應用的數據庫連接。默認false
spring.datasource.tomcat.remove-abandoned-timeout= # 在廢棄連接(仍在使用)可以被清除之前的超時描述。應把該值設定為應用可能具有的運行時間最長的查詢。默認60秒
spring.datasource.tomcat.rollback-on-return= # 如果`auto-commit=false`,那么當連接返回池中時,池會在連接上調用回滾方法,從而終止事務。默認false
spring.datasource.tomcat.suspect-timeout= # 超時時間(秒)。類似于`remove-abandoned-timeout`,但不會把連接當作廢棄連接從而有可能關閉連接。如果`log-abandoned`設為true,它只會記錄下警告。如果該值小于或等于0,則不會執行任何懷疑式檢查。如果超時值大于0,而連接還沒有被廢棄,或者廢棄檢查被禁用時,才會執行懷疑式檢查。如果某個連接被懷疑到,則記錄下WARN信息并發送一個JMX通知。默認0
spring.datasource.tomcat.test-on-borrow= # 從池中借出對象之前,是否對其進行驗證。如果驗證失敗,將其從池中清除,再接著去借下一個。為了讓true值生效,validation-query參數必須為非空字符串。為了實現更高效的驗證,可以采用vaildation-interval。默認false
spring.datasource.tomcat.test-on-connect= # 當一個連接首次被創建時是否進行驗證,若驗證失敗則拋出 SQLException 異常。默認 false
spring.datasource.tomcat.test-on-return= # 將對象返回池之前,是否對其進行驗證。為了讓true生效,validation-query參數必須為非空字符串。默認false
spring.datasource.tomcat.test-while-idle= ????????# 是否通過空閑對象清除者(如果存在)驗證對象。如果驗證失敗,則將其從池中清除。為了讓true生效,validation-query參數必須為非空字符串。默認false
spring.datasource.tomcat.time-between-eviction-runs-millis= # 在空閑連接回收器線程運行期間休眠時間(毫秒),該值不應該小于 1 秒,它決定線程多久驗證空閑連接或丟棄連接的頻率。默認5000
spring.datasource.tomcat.url=
spring.datasource.tomcat.use-disposable-connection-facade= # 如果希望在連接上放一個門面對象,從而使連接在關閉后無法重用,則要將值設為true。這能防止線程繼續引用一個已被關閉的連接,并繼續在連接上查詢。默認true
spring.datasource.tomcat.use-equals= # 如果想讓`ProxyConnection`類使用`String.equals`,則將該值設為true;若想在對比方法名稱時使用`==`,則應將其設置為false。該屬性不能用于任何已添加的攔截器中,因為那些攔截器都是分別配置的。默認true
spring.datasource.tomcat.use-lock=
spring.datasource.tomcat.use-statement-facade=
spring.datasource.tomcat.username= # 建立JDBC連接的用戶名。
spring.datasource.tomcat.validation-interval= # 避免過度驗證而設定的頻率時間值(秒)。最多以這種頻率運行驗證。如果連接應該進行驗證,但卻沒能在此間隔時間內得到驗證,則會重新對其進行驗證。默認30000(30秒)
spring.datasource.tomcat.validation-query= # 在連接池返回連接給調用者之前,用于驗證這些鏈接的SQL查詢。如果指定該值,則該查詢不必返回任何數據,只是不拋出SQLException異常。默認null。
spring.datasource.tomcat.validation-query-timeout= # SQL查詢驗證超時時間(秒)。通過在執行validation-query的語句上調用java.sql.Statement.setQueryTimeout(seconds)來實現。池本身并不會讓查詢超時,完全是由JDBC來強制實現。小于或等于0的數值表示禁用。默認-1
spring.datasource.tomcat.validator-class-name= # 實現org.apache.tomcat.jdbc.pool.Validator接口并提供了一個無參(可能是隱式的)構造函數的類名。如果指定該值,將通過該值來創建一個Validator實例來驗證連接,代替任何驗證查詢。默認null
dbcp2
commons-dbcp2
是Apache
上的一個Java連接池項目,與commons-dbcp
不相同。在 pom.xml
中引入 commons-dbcp2
依賴:
<dependency>
????<groupId>org.apache.commonsgroupId>
????<artifactId>commons-dbcp2artifactId>
????<version>2.7.0version>
dependency>
下面的配置會強制指定 commons-dbcp2
連接池。
spring.datasource.type=org.apache.commons.dbcp2.BasicDataSource
下面就開始在 application.properties
配置文件中配置commons-dbcp2
連接池的信息并綁定到org.apache.commons.dbcp2.BasicDataSource
中,如果不配置,Spring Boot 會使用默認配置信息。commons-dbcp2
的配置信息以 spring.datasource.dbcp2
開頭。
spring.datasource.dbcp2.abandoned-usage-tracking= # 默認false
spring.datasource.dbcp2.access-to-underlying-connection-allowed= # 控制PoolGuard是否允許訪問基礎連接。默認false
spring.datasource.dbcp2.auto-commit-on-return=
spring.datasource.dbcp2.cache-state=
spring.datasource.dbcp2.connection-factory-class-name=
spring.datasource.dbcp2.connection-init-sqls= # SQL語句的集合,將在首次創建連接時將其用于初始化。這些語句僅執行一次-當配置的連接工廠創建連接時。默認null
spring.datasource.dbcp2.default-auto-commit= # 連接池中創建的連接默認是否自動提交事務。
spring.datasource.dbcp2.default-catalog= # 連接池中創建的連接默認的 catalog
spring.datasource.dbcp2.default-query-timeout=
spring.datasource.dbcp2.default-read-only= # 連接池中創建的連接默認是否為只讀狀態。
spring.datasource.dbcp2.default-schema=
spring.datasource.dbcp2.default-transaction-isolation=
spring.datasource.dbcp2.disconnection-sql-codes= # 默認null
spring.datasource.dbcp2.driver=
spring.datasource.dbcp2.driver-class-name= # 驅動類的名稱
spring.datasource.dbcp2.eviction-policy-class-name=
spring.datasource.dbcp2.fast-fail-validation= # 默認false
spring.datasource.dbcp2.initial-size= # 連接池啟動時創建的初始連接數量。默認 0
spring.datasource.dbcp2.jmx-name= # 使用指定名稱將數據源注冊為JMX MBean。該名稱必須符合JMX對象名稱語法
spring.datasource.dbcp2.lifo= # true表示借用對象返回池中最近使用的(“后入”)連接(如果有可用的空閑連接)。false表示該池充當FIFO隊列-從空閑實例中獲取連接,并按返回到池的順序進行連接。默認true
spring.datasource.dbcp2.log-abandoned= # 默認false
spring.datasource.dbcp2.log-expired-connections= # 用于記錄指示由于超出`max-conn-lifetime-millis`而導致池正在關閉連接的消息的標記。設置false可禁止過期的連接日志記錄。默認true
spring.datasource.dbcp2.login-timeout=
spring.datasource.dbcp2.max-conn-lifetime-millis= # 一個連接的最大生命周期(毫秒)。小于或等于0,意味著無限時間。默認-1
spring.datasource.dbcp2.max-idle= # 可以在池中保持空閑的最大連接數,超出此值的空閑連接被釋放,負數表示不限制。默認8
spring.datasource.dbcp2.max-open-prepared-statements= # 可以同時從語句池分配的最大打開語句數,如果沒有限制,則為負數。
spring.datasource.dbcp2.max-total= # 連接池同一時間可分配的最大活躍連接數;負數表示不限制。默認 8
spring.datasource.dbcp2.max-wait-millis= # 最大等待時間(毫秒),如果在沒有連接可用的情況下等待超過此時間,則拋出異常;-1表示無期限等待,直到獲取到連接為止。
spring.datasource.dbcp2.min-evictable-idle-time-millis= # 連接在池中保持空閑而不被回收的最小時間(毫秒)。默認1800000
spring.datasource.dbcp2.min-idle= # 可以在池中保持空閑的最小連接數,低于此值將創建空閑連接,若設置為0,則不創建。默認0
spring.datasource.dbcp2.num-tests-per-eviction-run= # 空閑連接回收器線程運行期間檢查連接的個數。默認3
spring.datasource.dbcp2.password= # 數據庫密碼
spring.datasource.dbcp2.pool-prepared-statements= # 設置該連接池的預處理語句池是否生效。默認false
spring.datasource.dbcp2.remove-abandoned-on-borrow= # 標記是否刪除泄露的連接,如果連接超出 remove-abandoned-timeout 的限制,且該屬性設置為true,則連接被認為是被泄露并且可以被刪除。默認false
spring.datasource.dbcp2.remove-abandoned-on-maintenance= # 默認false
spring.datasource.dbcp2.remove-abandoned-timeout= # 泄露的連接可以被刪除的超時時間(秒),該值應設置為應用程序查詢可能執行的最長時間。默認300
spring.datasource.dbcp2.rollback-on-return=
spring.datasource.dbcp2.soft-min-evictable-idle-time-millis= # 默認-1
spring.datasource.dbcp2.test-on-borrow= # 當從連接池中取出一個連接時是否進行驗證,若驗證失敗則從池中刪除該連接并嘗試取出另一個連接。默認true
spring.datasource.dbcp2.test-on-create= # 連接在創建之后是否進行驗證。默認false
spring.datasource.dbcp2.test-on-return= # 當一個連接使用完歸還到連接池時是否進行驗證。默認false
spring.datasource.dbcp2.test-while-idle= # 對池中空閑的連接是否進行驗證,驗證失敗則釋放此連接。默認false
spring.datasource.dbcp2.time-between-eviction-runs-millis= # 空閑鏈接驗證/清除線程運行之間的休眠時間(毫秒)。不能低于1秒。該值決定了我們檢查空閑連接、廢棄連接的頻率,以及驗證空閑連接的頻率。默認5000(5秒)
spring.datasource.dbcp2.url= # 數據庫連接地址
spring.datasource.dbcp2.username= # 數據庫賬戶
spring.datasource.dbcp2.validation-query= # 在連接池返回連接給調用者前用來對連接進行驗證的查詢SQL
spring.datasource.dbcp2.validation-query-timeout= # SQL查詢驗證超時時間(秒)
原理
spring-boot-autoconfigure
依賴中jdbc
包下的DataSourceAutoConfiguration
是實現數據庫自動化配置數據源的類。:
@Configuration(
????proxyBeanMethods?=?false
)
//?關于類的條件主機(DataSource類、EmbeddedDatabaseType類存在于classpath時才生效)
@ConditionalOnClass({DataSource.class,?EmbeddedDatabaseType.class})
//?spring.datasource的配置項加載到DataSourceProperties的bean實例中
@EnableConfigurationProperties({DataSourceProperties.class})
//?導入DataSourcePoolMetadataProvidersConfiguration、DataSourceInitializationConfiguration類
//?DataSourcePoolMetadataProvidersConfiguration類根據引入的數據庫連接池實現提供相應的DataSourcePoolMetadataProvider
//?DataSourceInitializationConfiguration?是數據源配置的初始化相關類,同時引入?DataSourceInitializerInvoker(初始化數據庫的schema和sql語句,并實現監聽器)和Registrar(注冊)組件完成相關的初始化操作
@Import({DataSourcePoolMetadataProvidersConfiguration.class,?DataSourceInitializationConfiguration.class})public?class?DataSourceAutoConfiguration?{
????public?DataSourceAutoConfiguration()?{
????}
????static?class?EmbeddedDatabaseCondition?extends?SpringBootCondition?{
????????private?final?SpringBootCondition?pooledCondition?=?new?DataSourceAutoConfiguration.PooledDataSourceCondition();
????????EmbeddedDatabaseCondition()?{
????????}
????????public?ConditionOutcome?getMatchOutcome(ConditionContext?context,?AnnotatedTypeMetadata?metadata)?{
????????????Builder?message?=?ConditionMessage.forCondition("EmbeddedDataSource",?new?Object[0]);
????????????if?(this.anyMatches(context,?metadata,?new?Condition[]{this.pooledCondition}))?{
????????????????return?ConditionOutcome.noMatch(message.foundExactly("supported?pooled?data?source"));
????????????}?else?{
????????????????EmbeddedDatabaseType?type?=?EmbeddedDatabaseConnection.get(context.getClassLoader()).getType();
????????????????return?type?==?null???ConditionOutcome.noMatch(message.didNotFind("embedded?database").atAll())?:?ConditionOutcome.match(message.found("embedded?database").items(new?Object[]{type}));
????????????}
????????}
????}
????static?class?PooledDataSourceAvailableCondition?extends?SpringBootCondition?{
????????PooledDataSourceAvailableCondition()?{
????????}
????????public?ConditionOutcome?getMatchOutcome(ConditionContext?context,?AnnotatedTypeMetadata?metadata)?{
????????????Builder?message?=?ConditionMessage.forCondition("PooledDataSource",?new?Object[0]);
????????????return?DataSourceBuilder.findType(context.getClassLoader())?!=?null???ConditionOutcome.match(message.foundExactly("supported?DataSource"))?:?ConditionOutcome.noMatch(message.didNotFind("supported?DataSource").atAll());
????????}
????}
????static?class?PooledDataSourceCondition?extends?AnyNestedCondition?{
????????PooledDataSourceCondition()?{
????????????super(ConfigurationPhase.PARSE_CONFIGURATION);
????????}
????????@Conditional({DataSourceAutoConfiguration.PooledDataSourceAvailableCondition.class})static?class?PooledDataSourceAvailable?{
????????????PooledDataSourceAvailable()?{
????????????}
????????}
??//?通過spring.datasource.type屬性指定數據源類型,不指定的話則是默認
????????@ConditionalOnProperty(
????????????prefix?=?"spring.datasource",
????????????name?=?{"type"}
????????)
????????static?class?ExplicitType?{
????????????ExplicitType()?{
????????????}
????????}
????}
????@Configuration(
????????proxyBeanMethods?=?false
????)
????//?僅在類?PooledDataSourceCondition?條件滿足時生效
????//?PooledDataSourceCondition?會檢查所使用的數據源組件是否支持連接池
????@Conditional({DataSourceAutoConfiguration.PooledDataSourceCondition.class})
????//?僅在沒有類型為?DataSource/XADataSource?的?bean?定義時才生效
????@ConditionalOnMissingBean({DataSource.class,?XADataSource.class})
????//?導入針對數據源連接組件的數據源配置,這些配置僅在使用了相應的數據源連接組件時才生效。
????//?依據數據源導入順序,同時導入時的優先級?Hikari>Tomcat>Dbcp2
????@Import({Hikari.class,?Tomcat.class,?Dbcp2.class,?Generic.class,?DataSourceJmxConfiguration.class})protected?static?class?PooledDataSourceConfiguration?{
????????protected?PooledDataSourceConfiguration()?{
????????}
????}
????@Configuration(
????????proxyBeanMethods?=?false
????)
????//?僅在嵌入式數據庫被使用時才生效
????//?嵌入式數據庫這里指的是?H2、derby?或者?hsql
????@Conditional({DataSourceAutoConfiguration.EmbeddedDatabaseCondition.class})
????//?僅在沒有類型為?DataSource/XADataSource?的?bean?定義時才生效
????@ConditionalOnMissingBean({DataSource.class,?XADataSource.class})
????//?導入嵌入式數據庫有關的數據源配置
????//?提供的所使用的嵌入式數據庫的數據源?bean?EmbeddedDatabase
????@Import({EmbeddedDataSourceConfiguration.class})protected?static?class?EmbeddedDatabaseConfiguration?{
????????protected?EmbeddedDatabaseConfiguration()?{
????????}
????}
}
DataSourceConfiguration
的配置
abstract?class?DataSourceConfiguration?{
????DataSourceConfiguration()?{
????}
????//?DataSourceProperties中創建數據源
????protected?static??T?createDataSource(DataSourceProperties?properties,?Class?extends?DataSource>?type)?{return?properties.initializeDataSourceBuilder().type(type).build();
????}@Configuration(
????????proxyBeanMethods?=?false
????)@ConditionalOnMissingBean({DataSource.class})
????@ConditionalOnProperty(name?=?{"spring.datasource.type"}
????)static?class?Generic?{
????????Generic()?{
????????}//?提供的擴展點,自定義數據源@BeanDataSource?dataSource(DataSourceProperties?properties)?{//?使用?DataSourceBuilder?創建數據源,利用反射創建響應type的數據源,并且綁定相關屬性return?properties.initializeDataSourceBuilder().build();
????????}
????}@Configuration(
????????proxyBeanMethods?=?false
????)@ConditionalOnClass({BasicDataSource.class})
????@ConditionalOnMissingBean({DataSource.class})
????@ConditionalOnProperty(name?=?{"spring.datasource.type"},
????????havingValue?=?"org.apache.commons.dbcp2.BasicDataSource",
????????matchIfMissing?=?true
????)static?class?Dbcp2?{
????????Dbcp2()?{
????????}@Bean@ConfigurationProperties(
????????????prefix?=?"spring.datasource.dbcp2"
????????)BasicDataSource?dataSource(DataSourceProperties?properties)?{return?(BasicDataSource)DataSourceConfiguration.createDataSource(properties,?BasicDataSource.class);
????????}
????}@Configuration(
????????proxyBeanMethods?=?false
????)//?Spring?Boot?2.x?中默認的數據源@ConditionalOnClass({HikariDataSource.class})
????@ConditionalOnMissingBean({DataSource.class})
????@ConditionalOnProperty(name?=?{"spring.datasource.type"},
????????havingValue?=?"com.zaxxer.hikari.HikariDataSource",
????????matchIfMissing?=?true
????)static?class?Hikari?{
????????Hikari()?{
????????}@Bean@ConfigurationProperties(
????????????prefix?=?"spring.datasource.hikari"
????????)HikariDataSource?dataSource(DataSourceProperties?properties)?{
????????????HikariDataSource?dataSource?=?(HikariDataSource)DataSourceConfiguration.createDataSource(properties,?HikariDataSource.class);if?(StringUtils.hasText(properties.getName()))?{
????????????????dataSource.setPoolName(properties.getName());
????????????}return?dataSource;
????????}
????}@Configuration(
????????proxyBeanMethods?=?false
????)@ConditionalOnClass({org.apache.tomcat.jdbc.pool.DataSource.class})
????@ConditionalOnMissingBean({DataSource.class})
????@ConditionalOnProperty(name?=?{"spring.datasource.type"},
????????havingValue?=?"org.apache.tomcat.jdbc.pool.DataSource",
????????matchIfMissing?=?true
????)static?class?Tomcat?{
????????Tomcat()?{
????????}@Bean@ConfigurationProperties(
????????????prefix?=?"spring.datasource.tomcat"
????????)
????????org.apache.tomcat.jdbc.pool.DataSource?dataSource(DataSourceProperties?properties)?{
????????????org.apache.tomcat.jdbc.pool.DataSource?dataSource?=?(org.apache.tomcat.jdbc.pool.DataSource)DataSourceConfiguration.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;
????????}
????}
}
項目啟動后,會掃描 spring-boot-autoconfigure
依賴中下的spring.factories
文件進行自動配置。
配置Druid
Druid是alibaba提供的Java語言的數據庫連接池,能夠提供強大的監控和擴展功能。在 pom.xml
中導入 druid-spring-boot-starter
:
<dependency>
????<groupId>com.alibabagroupId>
????<artifactId>druid-spring-boot-starterartifactId>
????<version>1.1.22version>
dependency>
下面的配置會強制指定 druid
連接池。
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
下面就開始在 application.properties
配置文件中配置druid
連接池的信息并綁定到com.alibaba.druid.pool.DruidDataSource
中,如果不配置,Spring Boot 會使用默認配置信息。druid
的配置信息以 spring.datasource.druid
開頭。
# 連接池配置
spring.datasource.druid.initial-size= # 初始化時建立物理連接的個數
spring.datasource.druid.max-active= # 最大連接池數量 max-idle已經不再使用
spring.datasource.druid.min-idle= # 最小連接池數量
spring.datasource.druid.max-wait= # 獲取連接時最大等待時間(毫秒)。
spring.datasource.druid.pool-prepared-statements= # 是否緩存preparedStatement,mysql5.5+建議開啟
spring.datasource.druid.max-pool-prepared-statement-per-connection-size= #當值大于0時`pool-prepared-statements`會自動修改為true。
spring.datasource.druid.max-open-prepared-statements= #和上面的等價
spring.datasource.druid.validation-query= # 用來檢測連接是否有限的SQL查詢。
spring.datasource.druid.validation-query-timeout= # 檢查連接是否有效的超時時間。底層調用`jdbcStatement`對象的`void setQueryTimeout(int seconds)`方法。單位是秒。
spring.datasource.druid.test-on-borrow= # 申請連接時會執行`validation-query`檢測連接是否有效,開啟會降低性能。默認true
spring.datasource.druid.test-on-return= # 歸還連接時會執行`validation-query`檢測連接是否有效,開啟會降低性能。默認true
spring.datasource.druid.test-while-idle= # 申請連接的時候檢測,如果空閑時間大于`time-between-eviction-runs-millis`,執行`validation-query`檢查連接是否有效。
spring.datasource.druid.time-between-eviction-runs-millis= # 既作為檢測的間隔時間又作為`test-while-idel`執行的依據。
spring.datasource.druid.min-evictable-idle-time-millis= # 銷毀線程時檢測當前連接的最后活動時間和當前時間差大于該值時,關閉當前連接
spring.datasource.druid.max-evictable-idle-time-millis=
spring.datasource.druid.filters= ???????????????????????????????????????????????#配置多個英文逗號分隔
# 監控配置
# WebStatFilter配置,說明請參考Druid Wiki,配置_配置WebStatFilter
spring.datasource.druid.web-stat-filter.enabled= #是否啟用StatFilter默認值false
spring.datasource.druid.web-stat-filter.url-pattern=
spring.datasource.druid.web-stat-filter.exclusions=
spring.datasource.druid.web-stat-filter.session-stat-enable=
spring.datasource.druid.web-stat-filter.session-stat-max-count=
spring.datasource.druid.web-stat-filter.principal-session-name=
spring.datasource.druid.web-stat-filter.principal-cookie-name=
spring.datasource.druid.web-stat-filter.profile-enable=
本文使用的
Spring Boot
版本為2.2.1.RELEASE
,mysql-connector-java
版本為8.0.18
。