Springboot如何可以不屏蔽DataSourceAutoConfiguration这个类
这样写的启动类 非常的难看
上面 一定要排除这个DataSourceAutoConfiguration 感觉非常不舒服 那能不能不屏蔽这个类呢 当然可以首先看一下这个DataSourceAutoConfiguration的源码
通过源码可以看到 里面引入了两个类 一个 DataSource 一个 EmbeddedDatabaseType
下面对应两个方法 分别是 EmbeddedDatabaseConfiguration(嵌入式数据源的配置) 和 PooledDataSourceConfiguration (由DataSourceAutoConfiguration导入的实际数据源配置)
因为我用的mysql 所以 不是嵌入式数据库 我们只需要看 PooledDataSourceConfiguration 就可以了
上面导入了 四个一样的类中的不同的对象 我们来看下这个类
abstract class DataSourceConfiguration {
//创建一个 DataSource链接
@SuppressWarnings("unchecked")
protected static <T> T createDataSource(DataSourceProperties properties, Class<? extends DataSource> type) {
return (T) properties.initializeDataSourceBuilder().type(type).build();
}
/**
* Tomcat Pool DataSource configuration. tomcat代理的配置
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(org.apache.tomcat.jdbc.pool.DataSource.class)
@ConditionalOnMissingBean(DataSource.class)
@ConditionalOnProperty(name = "spring.datasource.type", havingValue = "org.apache.tomcat.jdbc.pool.DataSource",
matchIfMissing = true)
static class Tomcat {
@Bean
@ConfigurationProperties(prefix = "spring.datasource.tomcat")
org.apache.tomcat.jdbc.pool.DataSource dataSource(DataSourceProperties properties) {
org.apache.tomcat.jdbc.pool.DataSource dataSource = createDataSource(properties,
org.apache.tomcat.jdbc.pool.DataSource.class);
DatabaseDriver databaseDriver = DatabaseDriver.fromJdbcUrl(properties.determineUrl());
String validationQuery = databaseDriver.getValidationQuery();
if (validationQuery != null) {
dataSource.setTestOnBorrow(true);
dataSource.setValidationQuery(validationQuery);
}
return dataSource;
}
}
/**
* Hikari DataSource configuration. hikari配置
*/
@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;
}
}
/**
* DBCP DataSource configuration. DBCP配置
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(org.apache.commons.dbcp2.BasicDataSource.class)
@ConditionalOnMissingBean(DataSource.class)
@ConditionalOnProperty(name = "spring.datasource.type", havingValue = "org.apache.commons.dbcp2.BasicDataSource",
matchIfMissing = true)
static class Dbcp2 {
@Bean
@ConfigurationProperties(prefix = "spring.datasource.dbcp2")
org.apache.commons.dbcp2.BasicDataSource dataSource(DataSourceProperties properties) {
return createDataSource(properties, org.apache.commons.dbcp2.BasicDataSource.class);
}
}
/**
* Generic DataSource configuration. 通用配置
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingBean(DataSource.class)
@ConditionalOnProperty(name = "spring.datasource.type")
static class Generic {
@Bean
DataSource dataSource(DataSourceProperties properties) {
return properties.initializeDataSourceBuilder().build();
}
}
}
因为我用的Mysql 走的应该是 通用配置 这时候可以看到 传入了一个类 DataSourceProperties
查看源码得到 这是一个 获取spring.datasource 下面的输入的类 其中的initializeDataSourceBuilder 方法代码如下
可以看到 调用了一个新的类 DataSourceBuilder 源码如下 可以看到 上面调用的 initializeDataSourceBuilder 的 build 就是 DataSourceBuilder 的build 方法
build方法源码如下
@SuppressWarnings("unchecked")
public T build() {
Class<? extends DataSource> type = getType(); //获取数据库连接的类型
DataSource result = BeanUtils.instantiateClass(type); //返回一个DataSource
maybeGetDriverClassName();//获取大概的DriverClassName这个就是数据库连接的包
bind(result); //绑定
return (T) result;
}
这时候看下 获取 DriverClassName 的方法 是怎么写的 源码如下
private void maybeGetDriverClassName() {
if (!this.properties.containsKey("driverClassName") && this.properties.containsKey("url")) { //判断意思为 当driverClassName为空的时候 并且 有url的时候 调用下面的方法
String url = this.properties.get("url");
String driverClass = DatabaseDriver.fromJdbcUrl(url).getDriverClassName();
this.properties.put("driverClassName", driverClass);
}
}
通过源码 发现当不设置driverClassName 的时候 会调用下面的DatabaseDriver 根据url 寻找 driverClassName,DatabaseDriver 源码如下
从图片上可以看到 当我们配置的MySQL 的 driverClassName 正好为 com.mysql.cj.jdbc.Driver 就可以使用它的默认配置 也就是当我们的数据库版本为 MySQL8可以使用默认配置 不需要进行排除 只需要删除 spring.datasource.driverClassName 会根据这个默认的配置 自动配置