一.自动配置:springboot 自动配置功能会扫描所有引用jar包下的 META-INF/spring.factories 文件,找到其中的 org.springframework.boot.autoconfigure.EnableAutoConfiguration 对应的数据,作为自动配置类,然后根据条件判断是否加载它们。
二.自动配置与 DataSource:
DataSource 数据源的自动配置类是 DataSourceAutoConfiguration :
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@ConditionalOnMissingBean(type = "io.r2dbc.spi.ConnectionFactory")
@AutoConfigureBefore(SqlInitializationAutoConfiguration.class)
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({ DataSourcePoolMetadataProvidersConfiguration.class,
DataSourceInitializationConfiguration.InitializationSpecificCredentialsDataSourceInitializationConfiguration.class,
DataSourceInitializationConfiguration.SharedCredentialsDataSourceInitializationConfiguration.class })
public class DataSourceAutoConfiguration {}
1.其中 @ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class }) ,表示项目中必须存在 DataSource EmbeddedDatabaseType 这两个类,而 EmbeddedDatabaseType 是在 spring-boot-starter-jdbc 依赖包中的,所以需要引入
2.连接数据库需要引入驱动包,比如:mysql-connector-java
3.@EnableConfigurationProperties(DataSourceProperties.class) 表示启用DataSourceProperties 配置类,数据库的配置信息都在这个配置类中
4.Springboot 默认数据源是HikariDataSource,原因如下:
4.1DataSourceAutoConfiguration 被启用之后,内部存在一个配置类:
@Configuration(proxyBeanMethods = false)
@Conditional(PooledDataSourceCondition.class)
@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
@Import({ DataSourceConfiguration.Hikari.class, DataSourceConfiguration.Tomcat.class,
DataSourceConfiguration.Dbcp2.class, DataSourceConfiguration.OracleUcp.class,
DataSourceConfiguration.Generic.class, DataSourceJmxConfiguration.class })
protected static class PooledDataSourceConfiguration {}
默认情况下,上面的条件都会满足,需要关注 @Import 注解,这里导入了很多配置类,这些配置类上也会有各种 @Conditional… 条件显示,默认情况下只会有 DataSourceConfiguration.Hikari.class 配置类的条件满足,如下:
@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;
}
}
其中可以看到可以通过 spring.datasource.type 设置要使用的数据源类型,这里的 matchIfMissing = true 正是 HikariDataSource 成为默认数据源的关键,它表示如果spring.datasource.type 不配置的话,这个条件依然满足。
内部加载 HikariDataSource bean 的时候,可以看到标注了配置文件的前缀 spring.datasource.hikari ,其实这里的 DataSourceProperties 参数已经包含了使用前缀 spring.datasource 配置的数据库信息,而这些信息会被传递到 HikariDataSource 数据源中,而使用前缀 spring.datasource.hikari 的配置信息也会被应用到 HikariDataSource ,如果二者存在重复,spring.datasource.hikari 配置的数据会覆盖之前的配置。
以上就是 springboot 配置数据源以及HikariDataSource 作为默认数据源的逻辑,并且springboot 使用了spring.datasource.type 配置,控制了只会有一个 DataSource 实例被创建装载。