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 {
@ConditionalOnMissingBean
public 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


















