本文主要介绍
1. SpringBoot使用数据源配置方式;
2. SpringBoot默认连接池及自动配置原理(HikariCP);
3. SpringBoot替换默认连接池配置方式;
4. SpringBoot整合Druid连接池;
1. SpringBoot使用数据源配置方式
1.配置数据库驱动(Mysql为例)
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency>
2. SpringBoot核心配置文件中配置数据库连接信息
spring.datasource.url=jdbc:mysql:///test_mybatis?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.username=root spring.datasource.password=123456
3. 配置spring-boot-starter-jdbc
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency>
2. SpringBoot默认连接池及自动配置原理
SpringBoot 官方提供了三种数据库连接池 HikariCP, Commons DBCP2, Tomcat JDBC Connection Pool
默认使用的连接池是 HikariCP.
1. spring.factories中EnableAutoConfiguration中定义了数据源配置类:
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration ;
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({ DataSourcePoolMetadataProvidersConfiguration.class, DataSourceInitializationConfiguration.class })
public class DataSourceAutoConfiguration {
@Configuration(proxyBeanMethods = false)
@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 {
}
static class PooledDataSourceCondition extends AnyNestedCondition {
@ConditionalOnProperty(prefix = "spring.datasource", name = "type")
static class ExplicitType {
}
@Conditional(PooledDataSourceAvailableCondition.class)
static class PooledDataSourceAvailable {
}
}
2. DataSourceAutoConfiguration内部类PooledDataSourceConfiguration也是配置类PooledDataSourceConfiguration 中import了 DataSourceConfiguration下的Hikari,Tomcat,Dbcp2,Generic多个内部类
abstract class DataSourceConfiguration {protected static <T> T createDataSource(DataSourceProperties properties, Class<? extends DataSource> type) { // 使用DataSourceBuilder 建造数据源,利用反射创建type数据源,然后绑定相关属性 return (T) properties.initializeDataSourceBuilder().type(type).build(); } /** * Tomcat Pool DataSource configuration. */ @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. * //2.0 之后默认默认使用 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. */ @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. * //自定义连接池 接口 spring.datasource.type 配置 */ @Configuration(proxyBeanMethods = false) @ConditionalOnMissingBean(DataSource.class) @ConditionalOnProperty(name = "spring.datasource.type") static class Generic { @Bean DataSource dataSource(DataSourceProperties properties) { return properties.initializeDataSourceBuilder().build(); } }
3. 在 spring-boot-starter-jdbc 中,默认导入了HikariCP的jar,则DataSourceConfiguration中内部类 Hikari 条件注解生效,会执行
DataSourceConfiguration中的 createDataSource()方法
<artifactId>spring-boot-starter-jdbc</artifactId>
<name>Spring Boot JDBC Starter</name>
<description>Starter for using JDBC with the HikariCP connection pool</description>
<properties>
<main.basedir>${basedir}/../../..</main.basedir>
</properties>
<scm>
<url>${git.url}</url>
<connection>${git.connection}</connection>
<developerConnection>${git.developerConnection}</developerConnection>
</scm>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
</dependencies>
4. createDataSource方法调用了 getType()获取连接池类型;当配置文件中配置了spring.datasource.type 时,就加载配置的数据库连接池类型,如果没有配置就 调用findType(this.classLoader); 从DATA_SOURCE_TYPE_NAMES 中返回第一个类型即: com.zaxxer.hikari.HikariDataSource"
createDataSource(DataSourceProperties properties, Class<? extends DataSource> type) { return (T) properties.initializeDataSourceBuilder().type(type).build();
}
DataSourceBuilder{ public T build() { Class<? extends DataSource> type = getType(); DataSource result = BeanUtils.instantiateClass(type); maybeGetDriverClassName(); bind(result); return (T) result; }private Class<? extends DataSource> getType() { //如果没有配置type 则为空 默认选择 findType Class<? extends DataSource> type = (this.type != null) ? this.type : findType(this.classLoader); if (type != null) { return type; } throw new IllegalStateException("No supported DataSource type found"); }public static Class<? extends DataSource> findType(ClassLoader classLoader) { for (String name : DATA_SOURCE_TYPE_NAMES) { try { return (Class<? extends DataSource>) ClassUtils.forName(name, classLoader); } catch (Exception ex) { // Swallow and continue } } return null; }private static final String[] DATA_SOURCE_TYPE_NAMES = new String[] { "com.zaxxer.hikari.HikariDataSource", "org.apache.tomcat.jdbc.pool.DataSource", "org.apache.commons.dbcp2.BasicDataSource" };
3. SpringBoot替换默认连接池配置方式
1. 改用Commons DBCP2,移除 hikari 依赖引入DBCP2依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<exclusions>
<exclusion>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
</dependency>
2. 改用Tomcat JDBC Connection Pool 除 hikari 依赖引入tomcat-jdbc依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<exclusions>
<exclusion>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
</dependency>
4. SpringBoot整合Druid连接池
1. 引入Durid依赖
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency>
2. 增加DataSources配置类
@Configuration
public class DruidConfig {
@ConfigurationProperties(prefix = "spring.datasource")
@Bean
public DataSource druid() {
return new DruidDataSource();
}
}
3. 配置数据源信息
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql:///test_mybatis?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
driver-class-name: com.mysql.cj.jdbc.Driver
initialization-mode: always
# 使用druid数据源
type: com.alibaba.druid.pool.DruidDataSource
# 数据源其他配置
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filters: stat,wall,log4j
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
4. 引入log4j适配器(springBoot2.0后日志框架不再使用log4j,而是logback)
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </dependency>
本文详细介绍了SpringBoot中数据源的配置方法,包括添加MySQL驱动依赖、配置核心数据源属性以及引入spring-boot-starter-jdbc模块。接着,深入解析了SpringBoot默认使用HikariCP作为连接池的原因及其自动配置原理,涉及到DataSourceAutoConfiguration和DataSourceConfiguration的条件注解。此外,还展示了如何切换到CommonsDBCP2和TomcatJDBCConnectionPool。最后,演示了如何整合Druid连接池,包括引入依赖、配置DataSources及相应的数据源属性。
947

被折叠的 条评论
为什么被折叠?



