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,该对象的部分继承和实现关系是
SpringBoot底层-数据源自动配置类_第1张图片
可以看到DruidDataSourceWrapper实际上实现了DataSource接口,此时Spring容器内有一个DateSource类型的Bean。
回顾上面Hikari连接池的条件,此时@ConditionalOnMissingBean(DataSource.class)条件就不成立了,所以Hikari连接池就不会被实例化

总结

我们在IDEA里启动SpringBoot的控制台中也通过日志观察此时的数据源是否切换成了Druid

SpringBoot日志

SpringBoot 2和SpringBoot 3的依赖区别

SpringBoot 2需引入的druid依赖为druid-spring-boot-starter
SpringBoot 3需引入的druid依赖为druid-spring-boot-3-starter

你可能感兴趣的:(spring,boot,java,spring)