Springboot如何可以不屏蔽DataSourceAutoConfiguration这个类


这样写的启动类 非常的难看

springboot 屏蔽某个包的error日志 springboot屏蔽数据库_Source


上面 一定要排除这个DataSourceAutoConfiguration 感觉非常不舒服 那能不能不屏蔽这个类呢 当然可以首先看一下这个DataSourceAutoConfiguration的源码

springboot 屏蔽某个包的error日志 springboot屏蔽数据库_Source_02


通过源码可以看到 里面引入了两个类 一个 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 方法代码如下

springboot 屏蔽某个包的error日志 springboot屏蔽数据库_Source_03


可以看到 调用了一个新的类 DataSourceBuilder 源码如下 可以看到 上面调用的 initializeDataSourceBuilder 的 build 就是 DataSourceBuilder 的build 方法

springboot 屏蔽某个包的error日志 springboot屏蔽数据库_spring_04


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 源码如下

springboot 屏蔽某个包的error日志 springboot屏蔽数据库_Source_05

从图片上可以看到 当我们配置的MySQL 的 driverClassName 正好为 com.mysql.cj.jdbc.Driver 就可以使用它的默认配置 也就是当我们的数据库版本为 MySQL8可以使用默认配置 不需要进行排除 只需要删除 spring.datasource.driverClassName 会根据这个默认的配置 自动配置