SpringBoot底层-数据源自动配置类
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