在 Spring Boot 中,数据源的主动设置是框架中一个关键功能,本文将以 Spring Boot 2.1.7 版本为例,详细讲解在单数据源情况下数据源是如何主动加载的。我们通过源码分析,追踪整个加载流程。
1. 主动设置类的发现
Spring Boot 使用 spring.factories 机制加载主动设置类。在 org.springframework.boot.autoconfigure 包的 META-INF/spring.factories 文件中,可以找到:
- org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
- org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
复制代码 此中,DataSourceAutoConfiguration 是数据源的主动设置类。
2. DataSourceAutoConfiguration 类
进入 DataSourceAutoConfiguration 类,可以看到其内部有一个静态嵌套类 PooledDataSourceConfiguration:
- @Configuration
- @Conditional({PooledDataSourceCondition.class})
- @ConditionalOnMissingBean({DataSource.class, XADataSource.class})
- @Import({
- DataSourceConfiguration.Hikari.class,
- DataSourceConfiguration.Tomcat.class,
- DataSourceConfiguration.Dbcp2.class,
- DataSourceConfiguration.Generic.class,
- DataSourceJmxConfiguration.class
- })
- protected static class PooledDataSourceConfiguration {
- protected PooledDataSourceConfiguration() {
- }
- }
复制代码 关键点解释:
- @Conditional:依靠于 PooledDataSourceCondition 判断是否满足条件。
- @ConditionalOnMissingBean:确保没有自定义的 DataSource 和 XADataSource Bean。
- @Import:导入了 Hikari、Tomcat、Dbcp2 等数据源的设置类。
3. DataSourceConfiguration.Hikari 类
进入 DataSourceConfiguration.Hikari,这是 HikariCP 数据源的设置类(Tomcat、Dbcp2也类似):
- @Configuration
- @ConditionalOnClass({HikariDataSource.class})
- @ConditionalOnMissingBean({DataSource.class})
- @ConditionalOnProperty(
- name = {"spring.datasource.type"},
- havingValue = "com.zaxxer.hikari.HikariDataSource",
- matchIfMissing = true
- )
- static class Hikari {
- Hikari() {
- }
- @Bean
- @ConfigurationProperties(prefix = "spring.datasource.hikari")
- public HikariDataSource dataSource(DataSourceProperties properties) {
- HikariDataSource dataSource = (HikariDataSource)
- DataSourceConfiguration.createDataSource(properties, HikariDataSource.class);
-
- if (StringUtils.hasText(properties.getName())) {
- dataSource.setPoolName(properties.getName());
- }
- return dataSource;
- }
- }
复制代码 关键点解释:
- @ConditionalOnClass:确保 HikariDataSource 在类路径中存在,即有在pom文件中直接或间接的导入HikariCP依靠。
- @ConditionalOnMissingBean:如果没有本身定义其他 DataSource,则会加载此设置。
- @ConditionalOnProperty:当在application.yml或application.properties设置文件中 spring.datasource.type 的值是 HikariDataSource 或未定义时,匹配条件创建,使用 Hikari 数据源。
@ConditionalOnProperty具体用法可以看这篇:@ConditionalOnProperty
4. createDataSource 方法
进入 DataSourceConfiguration.createDataSource 方法:
- protected static <T> T createDataSource(DataSourceProperties properties, Class<? extends DataSource> type) {
- return properties.initializeDataSourceBuilder().type(type).build();
- }
复制代码 initializeDataSourceBuilder 方法采用了制作者模式对DataSourceBuilder对象举行了属性赋值。具体源码比较简单,各人可以本身点进去看看,要是看不懂可以先去看看制作者模式的文章。
制作者模式可以看这篇文章:制作者模式
5. DataSourceBuilder 的 build 方法
进入build 方法:
- public T build() {
- Class<? extends DataSource> type = this.getType();
- DataSource result = (DataSource)BeanUtils.instantiateClass(type);
- this.maybeGetDriverClassName();
- this.bind(result);
- return result;
- }
复制代码 关键步调:
- getType 方法:获取数据源的类型。
- BeanUtils.instantiateClass(type):通过反射实例化数据源对象。
- bind(result):将设置信息绑定到数据源对象。
6. getType 方法与默认数据源
在 getType 方法中,当 type 为 null 时,进入 findType 方法:
- private Class<? extends DataSource> getType() {
- Class<? extends DataSource> type = this.type != null
- ? this.type
- : findType(this.classLoader);
- if (type != null) {
- return type;
- } else {
- throw new IllegalStateException("No supported DataSource type found");
- }
- }
复制代码 findType 方法的实现:
- public static Class<? extends DataSource> findType(ClassLoader classLoader) {
- String[] var1 = DATA_SOURCE_TYPE_NAMES;
- for (String name : var1) {
- try {
- return ClassUtils.forName(name, classLoader);
- } catch (Exception ignored) {
- }
- }
- return null;
- }
- private static final String[] DATA_SOURCE_TYPE_NAMES = new String[]{
- "com.zaxxer.hikari.HikariDataSource",
- "org.apache.tomcat.jdbc.pool.DataSource",
- "org.apache.commons.dbcp2.BasicDataSource"
- };
复制代码 关键点解释:
- 默认数据源顺序:
- com.zaxxer.hikari.HikariDataSource(HikariCP)
- org.apache.tomcat.jdbc.pool.DataSource(Tomcat 数据源)
- org.apache.commons.dbcp2.BasicDataSource(DBCP2 数据源)
- 当 type 为 null 时,会按照顺序加载第一个可用的数据源,即 HikariCP。
7. 总结
通过以上分析,可以得出 Spring Boot 数据源主动加载的焦点流程:
- 加载主动设置类:通过 spring.factories 加载 DataSourceAutoConfiguration。
- 匹配数据源设置:判断条件,导入 Hikari、Tomcat、Dbcp2 等数据源设置类。
- 优先选择 HikariCP:如果未指定 spring.datasource.type,默认会选择 HikariCP 作为数据源。
- 数据源初始化:通过 DataSourceBuilder 使用责任链模式构建数据源对象。
8. 源码阅读发起
在阅读 Spring Boot 源码时,版本差异大概会导致设置逻辑有所差别,因此:
- 尽量选择与项目中一致的 Spring Boot 版本。
- 使用调试工具,逐步跟踪代码执行流程,理解主动设置的细节。
希望本文能帮助各人更好地理解 Spring Boot 2.1.7 数据源主动加载的过程,也接待各人在评论区留言,一起交换学习!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |