SpringBoot DataSource数据源实现自动配置流程详解

目录
  • 一、重点概念
    • 1、什么是DataSource数据源
    • 2、数据库连接池
  • 二、导入依赖
  • 三、分析自动配置
    • 1、DataSourceAutoConfiguration类
    • 2、DataSourceTransactionManagerAutoConfiguration类
    • 3、JdbcTemplateAutoConfiguration类
    • 4、JndiDataSourceAutoConfiguration类
    • 5、XADataSourceAutoConfiguration类
  • 四、代码样例

一、重点概念

1、什么是DataSource数据源

javax.sql.DataSource是由JDBC2.0 提供的接口,它负责建立与数据库的连接,当在应用程序中访问数据库时不必编写连接数据库的代码,直接引用DataSource获取数据库的连接对象即可。用于获取操作数据Connection对象

2、数据库连接池

当我们使用数据源建立多个数据库连接,这些数据库连接会保存在数据库连接池中,当需要访问数据库时,只需要从数据库连接池中获取空闲的数据库连接,当程序访问数据库结束时,数据库连接会放回数据库连接池中

二、导入依赖

首先我们需要导入JDBC相关场景

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>

然后,我们还需要导入数据库的连接驱动

注意,我们要根据数据库的版本去导入对应版本的驱动

因为Spring Boot它有默认的版本仲裁,即使不声明version也会有默认版本

所以我们可以直接修改依赖引入的版本(maven的就近依赖原则)或者在properties属性中重新声明版本(maven的属性的就近优先原则,下面使用的就是这种方式)

<properties>
	<mysql.version>5.1.49</mysql.version>
</properties>
...
<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<version>${mysql.version}</version>
</dependency>

三、分析自动配置

1、DataSourceAutoConfiguration类

从名字不难看出,这个类和数据源的自动配置有关

@AutoConfiguration(
    before = {SqlInitializationAutoConfiguration.class}
)
@ConditionalOnClass({DataSource.class, EmbeddedDatabaseType.class})
@ConditionalOnMissingBean(
    type = {"io.r2dbc.spi.ConnectionFactory"}
)
@EnableConfigurationProperties({DataSourceProperties.class})
@Import({DataSourcePoolMetadataProvidersConfiguration.class})
public class DataSourceAutoConfiguration {
    public DataSourceAutoConfiguration() {
    }
    ...

通过分析这个自动配置类,我们可以发现它绑定了一个DataSourceProperties.class配置类

@ConfigurationProperties(
    prefix = "spring.datasource"
)
public class DataSourceProperties implements BeanClassLoaderAware, InitializingBean {
    private ClassLoader classLoader;
    private boolean generateUniqueName = true;
    private String name;
    private Class<? extends DataSource> type;
    private String driverClassName;
    private String url;
    private String username;
    private String password;
    private String jndiName;
    private EmbeddedDatabaseConnection embeddedDatabaseConnection;
    private DataSourceProperties.Xa xa = new DataSourceProperties.Xa();
    private String uniqueName;
    ...

我们发现想要修改数据源相关的配置,只需要调整spring.datasource相关配置项即可

这里面有很多数据源的配置项,例如url、username等

在这个自动配置类中还有一个内嵌的配置类PooledDataSourceConfiguration

它在容器中没有DataSource.classXADataSource.class这两种类型的bean时才会生效

它使用@Import导入了针对不同数据库类型数据源连接组件的数据源配置,这些配置仅在使用了相应的数据源连接组件时才生效,一般开发人员只使用其中一种,所以也就只会有一个生效

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

我们随便点进一个它导入的数据源连接组件,跳转到DataSourceConfiguration类,可以看到我们前面自动导入的Hikari的相关配置如下,我们梳理一下这个类生效的条件

  • 容器中存在HikariDataSource.class类型的bean
  • 没有DataSource.class这个类型的bean
  • 系统配置项spring.datasource.type的值为com.zaxxer.hikari.HikariDataSource或者空

这里我们介绍一下matchIfMissing:当配置为空时,matchIfMissing为true,配置生效

@Configuration(
    proxyBeanMethods = false
)
@ConditionalOnClass({HikariDataSource.class})
@ConditionalOnMissingBean({DataSource.class})
@ConditionalOnProperty(
    name = {"spring.datasource.type"},
    havingValue = "com.zaxxer.hikari.HikariDataSource",
    matchIfMissing = true
)
static class Hikari {
    Hikari() {
    }
    @Bean
    @ConfigurationProperties(
        prefix = "spring.datasource.hikari"
    )
    HikariDataSource dataSource(DataSourceProperties properties) {
        HikariDataSource dataSource = (HikariDataSource)DataSourceConfiguration.createDataSource(properties, HikariDataSource.class);
        if (StringUtils.hasText(properties.getName())) {
            dataSource.setPoolName(properties.getName());
        }
        return dataSource;
    }
}

上述条件满足,所以底层配置好的连接池是:HikariDataSource

2、DataSourceTransactionManagerAutoConfiguration类

事务管理器的自动配置

3、JdbcTemplateAutoConfiguration类

这个是JdbcTemplate的自动配置,JdbcTemplate可以来对数据库进行crud

@AutoConfiguration(
    after = {DataSourceAutoConfiguration.class}
)
@ConditionalOnClass({DataSource.class, JdbcTemplate.class})
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties({JdbcProperties.class})
@Import({DatabaseInitializationDependencyConfigurer.class, JdbcTemplateConfiguration.class, NamedParameterJdbcTemplateConfiguration.class})
public class JdbcTemplateAutoConfiguration {
    public JdbcTemplateAutoConfiguration() {
    }
}

通过分析该自动配置类的配置绑定相关类代码可知,我们可以通过修改spring.jdbc开头的配置来对JdbcTemplate进行配置调整

@ConfigurationProperties(
    prefix = "spring.jdbc"
)
public class JdbcProperties {
    private final JdbcProperties.Template template = new JdbcProperties.Template();
    public JdbcProperties() {
    }
    public JdbcProperties.Template getTemplate() {
        return this.template;
    }

然后这个自动配置类导入的配置类又会去操作我们前面配置好的数据源

也就是下方jdbcTemplate()方法中的dataSource参数

@Configuration(
    proxyBeanMethods = false
)
@ConditionalOnMissingBean({JdbcOperations.class})
class JdbcTemplateConfiguration {
    JdbcTemplateConfiguration() {
    }
    @Bean
    @Primary
    JdbcTemplate jdbcTemplate(DataSource dataSource, JdbcProperties properties) {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
        Template template = properties.getTemplate();
        jdbcTemplate.setFetchSize(template.getFetchSize());
        jdbcTemplate.setMaxRows(template.getMaxRows());
        if (template.getQueryTimeout() != null) {
            jdbcTemplate.setQueryTimeout((int)template.getQueryTimeout().getSeconds());
        }
        return jdbcTemplate;
    }
}

4、JndiDataSourceAutoConfiguration类

Jndi自动配置

5、XADataSourceAutoConfiguration类

分布式事务的自动配置

四、代码样例

结合上面的源码分析,我们可以写一个简单的demo来进行数据库查询

首先我们去系统配置文件中定义一些关于数据源的配置项

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/decade_test?useUnicode=true&characterEncoding=UTF-8
    username: root
    password: root
    driver-class-name: com.mysql.jdbc.Driver

下面就是测试代码

package com.decade;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;
@SpringBootTest
@Slf4j
class SpringbootWebApplicationTests {
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Test
    void contextLoads() {
        final Long count = jdbcTemplate.queryForObject("select count(*) from t_decade_user", Long.class);
        log.info("该表中数据总数为{}", count);
    }
}

最后测试结果如图

到此这篇关于SpringBoot DataSource数据源实现自动配置流程详解的文章就介绍到这了,更多相关SpringBoot DataSource数据源配置内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Springboot mybatis plus druid多数据源解决方案 dynamic-datasource的使用详解

    依赖 <dependency> <groupId>com.baomidou</groupId> <artifactId>dynamic-datasource-spring-boot-starter</artifactId> <version>2.5.0</version> </dependency> <dependency> <groupId>p6spy</groupId>

  • 使用dynamic-datasource-spring-boot-starter实现多数据源及源码分析

    简介 前两篇博客介绍了用基本的方式做多数据源,可以应对一般的情况,但是遇到一些复杂的情况就需要扩展下功能了,比如:动态增减数据源.数据源分组,纯粹多库 读写分离 一主多从.从其他数据库或者配置中心读取数据源等等.其实就算没有这些需求,使用这个实现多数据源也比之前使用AbstractRoutingDataSource要便捷的多 dynamic-datasource-spring-boot-starter 是一个基于springboot的快速集成多数据源的启动器. github: https://g

  • SpringBoot +DynamicDataSource切换多数据源的全过程

    目录 固定多个数据源切换 1.由于我这个版本的自带DynamicDataSource包 2.在yml中配置两个数据源 3.启动时启动连接池的方法获取 4.载入各个连接池 5.dynamicDataSource类中 6.在切面中执行切换操作 刚开始用一个数据源,但是上头要求要做多数据源切换的.看了框架有自带的可以切数据源但是数据源是固定在YML文件的: 固定多个数据源切换 1.由于我这个版本的自带DynamicDataSource包 我就不引入了. 各位看官缺包自行去maven上查Dynamic-

  • SpringBoot默认使用HikariDataSource数据源方式

    目录 SpringBoot默认使用HikariDataSource数据源 定义 数据库连接 HikariDataSource默认配置 SpringBoot默认使用HikariDataSource数据源 定义 数据源:存储了所有建立数据库连接的信息.通过提供正确的数据源名称,你可以找到相应的数据库连接. 数据源负责维持一个数据库连接池,当程序创建数据源实例时,系统会一次性的创建多个数据库连接,并把这些数据连接保存在连接池中.当程序需要进行数据库访问时,无须重新获得数据库连接,而是从连接池中取出一个

  • SpringBoot基于AbstractRoutingDataSource实现多数据源动态切换

    目录 一.场景 二.原理 三.代码示例 一.场景 在生产业务中,有一些任务执行了耗时较长的查询操作,在实时性要求不高的时候,我们希望将这些查询sql分离出来,去从库查询,以减少应用对主数据库的压力. 一种方案是在配置文件中配置多个数据源,然后通过配置类来获取数据源以及mapper相关的扫描配置,不同的数据源配置不佟的mapper扫描位置,然后需要哪一个数据源就注入哪一个mapper接口即可,这种方法比较简单.特征是通过mapper扫描位置区分数据源. 第二种方案是配置一个默认使用的数据源,然后定

  • springboot+dynamicDataSource动态添加切换数据源方式

    目录 springboot dynamicDataSource动态添加切换数据源 1.修改初始加载的数据源map 2.此时一开始的时候就会加载数据库中的 3.但是发现新增数据源或修改数据源时无法操作 dynamicDataSource动态添加移除数据源 数据源model 切换接口 springboot dynamicDataSource动态添加切换数据源 之前有篇写了切换数据源的方法,那些可以在yml中配置固定的几个数据源进行切换后面需要新需求 在数据库实现增删改查数据源 然后连. 之前配置的就

  • springboot配置多数据源的一款框架(dynamic-datasource-spring-boot-starter)

    前言 前篇博客介绍了用基本的方式做多数据源,可以应对一般的情况,但是遇到一些复杂的情况就需要扩展下功能了,比如:动态增减数据源.数据源分组,纯粹多库,读写分离一主多从,从其他数据库或者配置中心读取数据源等等.其实就算没有这些需求,使用此款框架实现多数据源也比之前要便捷,快速的多 框架简介 dynamic-datasource-spring-boot-starter 是一个基于 springboot 的快速集成多数据源的启动器 文档:https://github.com/baomidou/dyna

  • SpringBoot2.0.3打印默认数据源为 HikariDataSource (null)问题

    目录 SpringBoot2.0.3打印默认数据源为 HikariDataSource (null) 打印结果 需要注意 springboot的HikariDataSource默认配置的默认值如下 SpringBoot2.0.3打印默认数据源为 HikariDataSource (null) 刚刚开始以为DataSource是空对象,后来打印了下面的语句,才知道DataSource不是空的,我砸,我就好奇为什么 打印出HikariDataSource (null) 这样的语句,真的坑. @Aut

  • SpringBoot DataSource数据源实现自动配置流程详解

    目录 一.重点概念 1.什么是DataSource数据源 2.数据库连接池 二.导入依赖 三.分析自动配置 1.DataSourceAutoConfiguration类 2.DataSourceTransactionManagerAutoConfiguration类 3.JdbcTemplateAutoConfiguration类 4.JndiDataSourceAutoConfiguration类 5.XADataSourceAutoConfiguration类 四.代码样例 一.重点概念 1

  • SpringBoot自动配置原理详解

    目录 阅读收获 一.SpringBoot是什么 二.SpringBoot的特点 三.启动类 3.1 @SpringBootApplication 四.@EnableAutoConfiguration 4.1 @AutoConfigurationPackage 4.2  @Import({AutoConfigurationImportSelector.class}) 五.流程总结图 六.常用的Conditional注解 七.@Import支持导入的三种方式 阅读收获 理解SpringBoot自动配

  • SpringBoot整合Mybatis与druid实现流程详解

    目录 SpringBoot整合junit SpringBoot整合junit SpringBoot整合junit的classes SpringBoot整合Mybatis 整合前的准备 整合Mybatis SpringBoot 整合druid 配置前置知识小点 整合druid SpringBoot整合junit SpringBoot整合junit ①还是一样,我们首先创建一个SpringBoot模块. 由于我们并不测试前端,而只是整合junit,所以不用选择模板,选择其中的web即可. 完成以后我

  • Redis Sentinel服务配置流程(详解)

    1.Redis Sentinel服务配置 1.1简介 Redis 的 Sentinel 系统用于管理多个 Redis 服务器(instance), 该系统执行以下三个任务: 监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常. 提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过API 向管理员或者其他应用程序发送通知. 自动故障迁移(Automatic failover): 当一个主服务器不

  • Admin - SpringBoot + Maven 多启动环境配置实例详解

    一:父级pom.xml文件 resources目录下新建指定文件夹,存放Spring配置文件 <profiles> <profile> <id>dev</id> <properties> <profiles.active>dev</profiles.active> </properties> <activation> <activeByDefault>true</activeByD

  • SpringBoot bean查询加载顺序流程详解

    目录 背景 探索-源码 进一步思考 背景 SpringBoot bean 加载顺序如何查看,想看加载了哪些bean, 这些bean的加载顺序是什么? 实际加载顺序不受控制,但会有一些大的原则: 1.按照字母顺序加载(同一文件夹下按照字母数序:不同文件夹下,先按照文件夹命名的字母顺序加载)2.不同的bean声明方式不同的加载时机,顺序总结:@ComponentScan > @Import > @Bean   这里的ComponentScan指@ComponentScan及其子注解,Bean指的是

  • SpringBoot原理之自动配置机制详解

    目录 前言 Spring配置类 SpringBoot自动配置 自动配置的概念 自动配置的运行机制 加载方式 SpringFactoriesLoader机制 SpringFactoriesLoader如何应用在自动配置中 小结 前言 在当下的java生态里,SpringBoot已经成为事实上的开发标准,绝大多数人现在都是面向SpringBoot编程.SpringBoot是对Spring的进一步封装,整合了分布式系统上下游所需的各种类库和组件,并且实现了开箱即用,而这一切的底层基础就是SpringB

  • Spring boot中@Conditional和spring boot的自动配置实例详解

    我们知道,spring boot自动配置功能可以根据不同情况来决定spring配置应该用哪个,不应该用哪个,举个例子: Spring的JdbcTemplate是不是在Classpath里面?如果是,并且DataSource也存在,就自动配置一个JdbcTemplate的Bean Thymeleaf是不是在Classpath里面?如果是,则自动配置Thymeleaf的模板解析器.视图解析器.模板引擎 那个这个是怎么实现的呢?原因就在于它利用了Spring的条件化配置,条件化配置允许配置存在于应用中

  • Springboot整合JPA配置多数据源流程详解

    目录 1. Maven 2. 基本配置 DataSource 3. 多数据源配置 3.1 JpaConfigOracle 3.2 JpaConfigMysql 4. Dao层接口 1. Maven <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>

  • SpringBoot集成Nacos实现注册中心与配置中心流程详解

    目录 SpringBoot整合Nacos 引入Maven依赖 增加配置 示例代码 SpringBoot整合Nacos 引入Maven依赖 首先,我们还是要引入 Maven 依赖 <!--注册中心的依赖--> <dependency> <groupId>com.alibaba.boot</groupId> <artifactId>nacos-discovery-spring-boot-starter</artifactId> <v

随机推荐