文章目录
-
-
-
- SpringBoot 默认的数据源是什么?
- DruidDataSource 是如何被加载的?
- Failed to configure a DataSource 这个错见过吗?
-
-
SpringBoot 默认的数据源是什么?
先把目光聚焦在DataSourceAutoConfiragution(spring-boot-autoconfigure),根据SpringBoot自动装配的特性可知,
@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 {
}
PooledDataSourceConfiguration类会引入这么多Java Config。这里主要关注DataSourceConfiguration.Hikari
@Configuration
@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")
public HikariDataSource dataSource(DataSourceProperties properties) {
HikariDataSource dataSource = createDataSource(properties,
HikariDataSource.class);
if (StringUtils.hasText(properties.getName())) {
dataSource.setPoolName(properties.getName());
}
return dataSource;
}
}
从上面的配置可以看到,只要ClassPath中存在类
HikariDataSource
且不存在
DataSource
的Bean,就会去构造HikariDataSource.
这里需要注意两点:1、入参DataSourceProperties 2、createDataSource()方法
DataSourceProperties就是我们平常配置在application.properties中属性对应的实体,例如
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.password=root
spring.datasource.username=root
spring.datasource.url=jdbc:mysql://localhost:3306/ds0?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8
HikariDataSource的构造过程 createDataSource
protected static <T> T createDataSource(DataSourceProperties properties,
Class<? extends DataSource> type) {
return (T) properties.initializeDataSourceBuilder().type(type).build();
}
这里的type是前面传入的
HikariDataSource
,这里主要是使用配置中的用户名、密码、url等构造HikariDataSource实例
因此 可以说 默认SpringBoot的数据源是
HikariDataSource
DruidDataSource 是如何被加载的?
移步到DruidDataSourceAutoConfigure一看便知
@Configuration
@ConditionalOnClass(DruidDataSource.class)
@AutoConfigureBefore(DataSourceAutoConfiguration.class)
@EnableConfigurationProperties({DruidStatProperties.class, DataSourceProperties.class})
@Import({DruidSpringAopConfiguration.class,
DruidStatViewServletConfiguration.class,
DruidWebStatFilterConfiguration.class,
DruidFilterConfiguration.class})
public class DruidDataSourceAutoConfigure {
private static final Logger LOGGER = LoggerFactory.getLogger(DruidDataSourceAutoConfigure.class);
@Bean(initMethod = "init")
@ConditionalOnMissingBean
public DataSource dataSource() {
LOGGER.info("Init DruidDataSource");
return new DruidDataSourceWrapper();
}
}
DruidStatProperties 这个DruidDataSource属性配置类,前缀为spring.datasource.druid
DataSourceProperties是默认数据源属性配置类,它们两者的关系是 若有些配置没有在DruidStatProperties 中找到,则尝试去DataSourceProperties找配置
Failed to configure a DataSource 这个错见过吗?
其实 这个错通常完整的描述是
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
Reason: Failed to determine suitable jdbc url
Action:
Consider the following:
If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active).
通常遇到这种问题,是项目里引入了第三方数据源导致的,比如DruidDataSource,以Druid数据源为例,它需要一些自己的配置,如spring.datasource.druid.xxx
虽然引入了Druid的starter,但是默认的DataSourceAutoConfiguration也会被加载,HikariDataSource也会被创建,而创建HikariDataSource时 需要的一些属性可能没有被设置 就引发了前面说的报错
解决方式:
如要使用第三方数据源如DruidDataSource,则必须在SpringBoot启动类排除
DataSourceAutoConfiguration
,如