SpringBoot默認使用Hikari連接池,當我們想要切換成Druid連接池,底層原理是怎樣呢
SpringBoot默認連接池——Hikari
在spring-boot-autoconfiguration
包內有一個DataSourceConfiguraion
配置類
abstract class DataSourceConfiguration {@Configuration(proxyBeanMethods = false)@ConditionalOnClass(HikariDataSource.class)@ConditionalOnMissingBean(DataSource.class)@ConditionalOnProperty(name = "spring.datasource.type", havingValue = "com.zaxxer.hikari.HikariDataSource", matchIfMissing = true)static class Hikari {@Bean@ConfigurationProperties(prefix = "spring.datasource.hikari")HikariDataSource dataSource(DataSourceProperties properties) {HikariDataSource dataSource = createDataSource(properties, HikariDataSource.class);if (StringUtils.hasText(properties.getName())) {dataSource.setPoolName(properties.getName());}return dataSource;}}
}
@ConditionalOnClass(HikariDataSource.class)
Hikari包會自動導入,這個條件默認滿足@ConditionalOnMissingBean(DataSource.class)
當不存在DataSource
類型的Bean
,這個條件為后續切換到Druid
連接池做鋪墊@ConditionalOnProperty(name = "spring.datasource.type", havingValue = "com.zaxxer.hikari.HikariDataSource", matchIfMissing = true)
中的matchIfMissing = true
是重點,表示假如配置項沒有這個配置spring.datasource.type=com.zaxxer.hikari.HikariDataSource
,也滿足這個條件
所以當spring.datasource.type
沒有被配置的時候,SpringBoot的自動配置會默認使用Hikari
連接池
切換到Druid連接池
當我們在maven中引入druid-spring-boot-starter
依賴的時候,就會有DruidDataSourceAutoConfigure
配置類
@ConditionalOnClass({DruidDataSource.class})
@AutoConfigureBefore({DataSourceAutoConfiguration.class})
public class DruidDataSourceAutoConfigure {@ConditionalOnMissingBeanpublic DataSource dataSource() {return new DruidDataSourceWrapper();}
}class DruidDataSourceWrapper extends DruidDataSource implements InitializingBean {}
@ConditionalOnClass({DruidDataSource.class})
導入DruidDataSource
類,默認滿足條件@AutoConfigureBefore({DataSourceAutoConfiguration.class})
這個是切換數據源的核心,表示在DataSourceAutoConfiguration
配置類前自動裝配,所以Druid
連接池配置類優先于SpringBoot默認的數據源配置類DataSourceConfiguraion
自動裝配。
DruidDataSourceAutoConfigure
在自動裝配時會實例化一個數據源對象DruidDataSourceWrapper
,該對象的部分繼承和實現關系是
可以看到DruidDataSourceWrapper
實際上實現了DataSource
接口,此時Spring容器內有一個DateSource
類型的Bean。
回顧上面Hikari
連接池的條件,此時@ConditionalOnMissingBean(DataSource.class)
條件就不成立了,所以Hikari
連接池就不會被實例化
總結
我們在IDEA里啟動SpringBoot的控制臺中也通過日志觀察此時的數據源是否切換成了Druid
SpringBoot 2和SpringBoot 3的依賴區別
SpringBoot 2需引入的druid依賴為druid-spring-boot-starter
SpringBoot 3需引入的druid依賴為druid-spring-boot-3-starter