由springboot默认数据库连接池学习到的内容

由springboot默认数据库连接池学习到的内容

springboot在2.x之后默认数据库连接池为Hikari

那么在springboot是如何设置默认数据库连接池的呢?

通过查询资料得知,springboot默认设置数据库连接池的原理为DataSourceAutoConfiguration
此源码为:

/*
 * Copyright 2012-2021 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.boot.autoconfigure.jdbc;

@SuppressWarnings("deprecation")
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@ConditionalOnMissingBean(type = "io.r2dbc.spi.ConnectionFactory")
@AutoConfigureBefore(SqlInitializationAutoConfiguration.class)
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({ DataSourcePoolMetadataProvidersConfiguration.class,
		DataSourceInitializationConfiguration.InitializationSpecificCredentialsDataSourceInitializationConfiguration.class,
		DataSourceInitializationConfiguration.SharedCredentialsDataSourceInitializationConfiguration.class })
public class DataSourceAutoConfiguration {

	@Configuration(proxyBeanMethods = false)
	@Conditional(EmbeddedDatabaseCondition.class)
	@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
	@Import(EmbeddedDataSourceConfiguration.class)
	protected static class EmbeddedDatabaseConfiguration {

	}

	@Configuration(proxyBeanMethods = false)
	@Conditional(PooledDataSourceCondition.class)
	@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
	@Import({ DataSourceConfiguration.Hikari.class, DataSourceConfiguration.Tomcat.class,
			DataSourceConfiguration.Dbcp2.class, DataSourceConfiguration.OracleUcp.class,
			DataSourceConfiguration.Generic.class, DataSourceJmxConfiguration.class })
	protected static class PooledDataSourceConfiguration {

	}

	/**
	 * {@link AnyNestedCondition} that checks that either {@code spring.datasource.type}
	 * is set or {@link PooledDataSourceAvailableCondition} applies.
	 */
	static class PooledDataSourceCondition extends AnyNestedCondition {

		PooledDataSourceCondition() {
			super(ConfigurationPhase.PARSE_CONFIGURATION);
		}

		@ConditionalOnProperty(prefix = "spring.datasource", name = "type")
		static class ExplicitType {

		}

		@Conditional(PooledDataSourceAvailableCondition.class)
		static class PooledDataSourceAvailable {

		}

	}

	/**
	 * {@link Condition} to test if a supported connection pool is available.
	 */
	static class PooledDataSourceAvailableCondition extends SpringBootCondition {

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

	}

	/**
	 * {@link Condition} to detect when an embedded {@link DataSource} type can be used.
	 * If a pooled {@link DataSource} is available, it will always be preferred to an
	 * {@code EmbeddedDatabase}.
	 */
	static class EmbeddedDatabaseCondition extends SpringBootCondition {

		private static final String DATASOURCE_URL_PROPERTY = "spring.datasource.url";

		private final SpringBootCondition pooledCondition = new PooledDataSourceCondition();

		@Override
		public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
			ConditionMessage.Builder message = ConditionMessage.forCondition("EmbeddedDataSource");
			if (hasDataSourceUrlProperty(context)) {
				return ConditionOutcome.noMatch(message.because(DATASOURCE_URL_PROPERTY + " is set"));
			}
			if (anyMatches(context, metadata, this.pooledCondition)) {
				return ConditionOutcome.noMatch(message.foundExactly("supported pooled data source"));
			}
			EmbeddedDatabaseType type = EmbeddedDatabaseConnection.get(context.getClassLoader()).getType();
			if (type == null) {
				return ConditionOutcome.noMatch(message.didNotFind("embedded database").atAll());
			}
			return ConditionOutcome.match(message.found("embedded database").items(type));
		}

		private boolean hasDataSourceUrlProperty(ConditionContext context) {
			Environment environment = context.getEnvironment();
			if (environment.containsProperty(DATASOURCE_URL_PROPERTY)) {
				try {
					return StringUtils.hasText(environment.getProperty(DATASOURCE_URL_PROPERTY));
				}
				catch (IllegalArgumentException ex) {
					// Ignore unresolvable placeholder errors
				}
			}
			return false;
		}

	}

}

在阅读源码的过程中,对于几个注解比较关注

首先是:

@Configuration(proxyBeanMethods = false)

以前在写一些配置类的时候,经常使用@Configuration注解,这里加了一个属性的作用是什么?

其实通过名字就能大概了解,proxyBeanMethods设置为FALSE时,不会代理@Bean方法,也就是说,通过@Bean注解标记的方法为普通方法,不会存在bean的生命周期

@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })

conditional->有条件的

这里的作用是当容器中存在DataSource.class, EmbeddedDatabaseType.class的时候,被该注解标记的类才会被注入

@ConditionalOnMissingBean(type = "io.r2dbc.spi.ConnectionFactory")

当不存在参数中bean的时候,才会初始化

@AutoConfigureBefore(SqlInitializationAutoConfiguration.class)

被此注解标记的class会在参数中class初始化之前初始化

@Import(EmbeddedDataSourceConfiguration.class)

该注解的功能类似于@Bean注解,但是比@Bean注解更加快速

它可以将一个普通类注入到IOC容器中,进而可以使用@Autowirde等方式作为依赖注入普通类

还有有需要注意的地方是通过此方法注入的类的bean name为全类名

进而还有两种方法可以对该方法做一些自定义

@Conditional(PooledDataSourceCondition.class)

image-20220113000452063

这是一个条件注解,被该注解标记的类需要满足参数中类的match方法才能被初始化,参数需要继承Condition类

image-20220113000716086

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot 基础教程(基于1.3.x-1.5.x) 快速入门 chapter1:基本项目构建(可作为工程脚手架),引入web模块,完成一个简单的RESTful API 使用Intellij中的Spring Initializr来快速构建Spring Boot/Cloud工程 工程配置 chapter2-1-1:配置文件详解:自定义属性、随机数、多环境配置等 chapter2-1-2:2.0 新特性(一):配置绑定全解析 chapter2-2-1:2.0 新特性(二):新增事件ApplicationStartedEvent Web开发 chapter3-1-1:构建一个较为复杂的RESTful API以及单元测试 chapter3-1-2:使用Thymeleaf模板引擎渲染web视图 chapter3-1-3:使用Freemarker模板引擎渲染web视图 chapter3-1-4:使用Velocity模板引擎渲染web视图 chapter3-1-5:使用Swagger2构建RESTful API chapter3-1-6:统一异常处理 chapter3-1-7:使用Java 8中LocalDate等时间日期类的问题解决 chapter3-1-8:扩展XML请求和响应的支持 数据访问 chapter3-2-1:使用JdbcTemplate chapter3-2-2:使用Spring-data-jpa简化数据访问层(推荐) chapter3-2-3:多数据源配置(一):JdbcTemplate chapter3-2-4:多数据源配置(二):Spring-data-jpa chapter3-2-5:使用NoSQL数据库(一):Redis chapter3-2-6:使用NoSQL数据库(二):MongoDB chapter3-2-7:整合MyBatis chapter3-2-8:MyBatis注解配置详解 chapter3-2-9:使用Flyway来管理数据库版本 chapter3-2-10:使用LDAP来统一管理用户信息 chapter3-2-11:Spring Boot中增强对MongoDB的配置(连接池等) 事务管理 chapter3-3-1:使用事务管理 chapter3-3-2:[分布式事务(未完成)] 其他内容 chapter4-1-1:使用@Scheduled创建定时任务 chapter4-1-2:使用@Async实现异步调用 chapter4-1-3:使用@Async实现异步调用:自定义线程池 chapter4-1-4:使用@Async实现异步调用:资源优雅关闭 chapter4-1-5:使用@Async实现异步调用:使用Future以及定义超时 日志管理 chapter4-2-1:默认日志的配置 chapter4-2-2:使用log4j记录日志 chapter4-2-3:对log4j进行多环境不同日志级别的控制 chapter4-2-4:使用AOP统一处理Web请求日志 chapter4-2-5:使用log4j记录日志到MongoDB chapter4-2-6:Spring Boot 1.5.x新特性:动态修改日志级别] 安全管理 chapter4-3-1:使用Spring Security chapter4-3-2:[使用Spring Session(未完成)] 缓存支持 chapter4-4-1:注解配置与EhCache使用 chapter4-4-2:使用Redis做集中式缓存 邮件发送 chapter4-5-1:实现邮件发送:简单邮件、附件邮件、嵌入资源的邮件、模板邮件 消息服务 chapter5-1-1:[JMS(未完成)] chapter5-2-1:Spring Boot中使用RabbitMQ 其他功能 chapter6-1-1:使用Spring StateMachine框架实现状态机 Spring Boot Actuator监控端点小结 在传统Spring应用中使用spring-boot-actuator模块提供监控端点 Spring Boot应用的后台运行配置 Spring Boot自定义Banner Dubbo进行服务治理 chapter9-2-1:Spring Boot中使用Dubbo进行服务治理 chapter9-2-2:Spring Boot与Dubbo中管理服务依赖

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值