Springboot自动配置原理及DataSource的应用方式
作者:蜡笔白阁下
自动配置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 实例被创建装载。
这些仅为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。