springboot 中数据源配置,连接池配置,源码剖析,如何选择连接池

springboot系列学习笔记全部文章请移步值博主专栏**: spring boot 2.X/spring cloud Greenwich。
由于是一系列文章,所以后面的文章可能会使用到前面文章的项目。springboot系列代码全部上传至GitHub:https://github.com/liubenlong/springboot2_demo
本系列环境:Java11;springboot 2.1.1.RELEASE;springcloud Greenwich.RELEASE;MySQL 8.0.5;

文章目录

  • 参考文档

之前讲了springboot中如何配置MySQL以及配置多数据源,参数也都配置好了,那么springboot中到底如何选择的呢?

声明:笔者使用的springboot版本是1.5.3.RELEASE

springboot自动装配的过程就不说了,直接上核心代码。

org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration该类是springboot加载数据源的核心配置类。
我们去看连接池的选择:

@Configuration
	@Conditional(PooledDataSourceCondition.class)
	@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
	@Import({ DataSourceConfiguration.Tomcat.class, DataSourceConfiguration.Hikari.class,
			DataSourceConfiguration.Dbcp.class, DataSourceConfiguration.Dbcp2.class,
			DataSourceConfiguration.Generic.class })
	@SuppressWarnings("deprecation")
	protected static class PooledDataSourceConfiguration {

	}

PooledDataSourceConfiguration上面的注解包含了tomcat连接池,dbcp,dbcp2等主流连接池。到底选择哪个连接池呢?(选择不同的连接池,application.properties配置不同
一步一步往下跟:
进入PooledDataSourceCondition
进入PooledDataSourceAvailableCondition

static class PooledDataSourceAvailableCondition extends SpringBootCondition {

		@Override
		public ConditionOutcome getMatchOutcome(ConditionContext context,
				AnnotatedTypeMetadata metadata) {
			ConditionMessage.Builder message = ConditionMessage
					.forCondition("PooledDataSource");
			if (getDataSourceClassLoader(context) != null) {
				return ConditionOutcome
						.match(message.foundExactly("supported DataSource"));
			}
			return ConditionOutcome
					.noMatch(message.didNotFind("supported DataSource").atAll());
		}

		/**
		 * Returns the class loader for the {@link DataSource} class. Used to ensure that
		 * the driver class can actually be loaded by the data source.
		 * @param context the condition context
		 * @return the class loader
		 */
		private ClassLoader getDataSourceClassLoader(ConditionContext context) {
			Class dataSourceClass = new DataSourceBuilder(context.getClassLoader())
					.findType();/*找到源头了*/
			return (dataSourceClass == null ? null : dataSourceClass.getClassLoader());
		}

	}

进入findtype方法:

public Class findType() {
		if (this.type != null) {
			return this.type;
		}
		for (String name : DATA_SOURCE_TYPE_NAMES) {
			try {
				return (Class) ClassUtils.forName(name,
						this.classLoader);
			}
			catch (Exception ex) {
				// Swallow and continue
			}
		}
		return null;
	}

里面有一个常量数组:

private static final String[] DATA_SOURCE_TYPE_NAMES = new String[] {
			"org.apache.tomcat.jdbc.pool.DataSource",
			"com.zaxxer.hikari.HikariDataSource",
			"org.apache.commons.dbcp.BasicDataSource", // deprecated
			"org.apache.commons.dbcp2.BasicDataSource" };

findType()方法中遍历该数组,从前往后,加载到哪个类就使用哪个类的连接池。
可能会因为不同项目中类不同,导致使用不同的连接池,所以最好就是在这里加个断点,亲自看一下最终选定的是哪个连接池

springboot 中数据源配置,连接池配置,源码剖析,如何选择连接池_第1张图片

上图可见,笔者使用的是Tomcat连接池:org.apache.tomcat.jdbc.pool.DataSource

进入org.springframework.boot.autoconfigure.jdbc.DataSourceInitializer类,里面有init方法,是启动的时候加载的。属性文件以及datasource的配置就是在这里完成的。

@PostConstruct
	public void init() {
		if (!this.properties.isInitialize()) {
			logger.debug("Initialization disabled (not running DDL scripts)");
			return;
		}
		if (this.applicationContext.getBeanNamesForType(DataSource.class, false,
				false).length > 0) {
				//加载dataSource 类,确认使用哪个连接池,
			this.dataSource = this.applicationContext.getBean(DataSource.class);
		}
		if (this.dataSource == null) {//在这里查看DataSource的配置信息
			logger.debug("No DataSource found so not initializing");
			return;
		}
		runSchemaScripts();
	}

在这里加个断点 ,查看最终使用的哪个连接池,以及我们的配置是否生效。
springboot 中数据源配置,连接池配置,源码剖析,如何选择连接池_第2张图片

好了,接下来就是去看源码org.apache.tomcat.jdbc.pool.DataSource或者官方文档,去配置参数了.
配置信息可以参考这两个类:

public class DataSourceProxy implements PoolConfiguration {
    private static final Log log = LogFactory.getLog(DataSourceProxy.class);
	//链接配置
    protected volatile ConnectionPool pool = null;
	//连接池配置
    protected volatile PoolConfiguration poolProperties = null;
    
    //省略代码......
}

springboot系列学习笔记全部文章请移步值博主专栏**: spring boot 2.X/spring cloud Greenwich。
由于是一系列文章,所以后面的文章可能会使用到前面文章的项目。springboot系列代码全部上传至GitHub:https://github.com/liubenlong/springboot2_demo
本系列环境:Java11;springboot 2.1.1.RELEASE;springcloud Greenwich.RELEASE;MySQL 8.0.5;

参考文档

测试DB连接,最大等待时间,DB测试
使用druid连接池带来的坑testOnBorrow=false

你可能感兴趣的:(java/java8,mysql,springboot,spring,boot,2.X/spring,cloud,Greenwich)