广告位联系
返回顶部
分享到

SpringBoot DataSource数据源实现自动配置流程介绍

java 来源:互联网 作者:佚名 发布时间:2022-10-06 23:08:53 人浏览
摘要

一、重点概念 1、什么是DataSource数据源 javax.sql.DataSource是由JDBC2.0 提供的接口,它负责建立与数据库的连接,当在应用程序中访问数据库时不必编写连接数据库的代码,直接引用DataSou

一、重点概念

1、什么是DataSource数据源

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

2、数据库连接池

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

二、导入依赖

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

1

2

3

4

<dependency>

    <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-starter-data-jdbc</artifactId>

</dependency>

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

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

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

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

1

2

3

4

5

6

7

8

9

<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类

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

1

2

3

4

5

6

7

8

9

10

11

12

13

@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配置类

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

@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.class和XADataSource.class这两种类型的bean时才会生效

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

1

2

3

4

5

6

7

8

9

10

@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,配置生效

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

@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

1

2

3

4

5

6

7

8

9

10

11

@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进行配置调整

1

2

3

4

5

6

7

8

9

10

@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参数

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

@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

下面就是测试代码

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

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);

    }

}

最后测试结果如图


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 : https://blog.csdn.net/Decade0712/article/details/127096976
相关文章
  • SpringBoot自定义错误处理逻辑介绍

    SpringBoot自定义错误处理逻辑介绍
    1. 自定义错误页面 将自定义错误页面放在 templates 的 error 文件夹下,SpringBoot 精确匹配错误信息,使用 4xx.html 或者 5xx.html 页面可以打印错误
  • Java实现手写一个线程池的代码

    Java实现手写一个线程池的代码
    线程池技术想必大家都不陌生把,相信在平时的工作中没有少用,而且这也是面试频率非常高的一个知识点,那么大家知道它的实现原理和
  • Java实现断点续传功能的代码

    Java实现断点续传功能的代码
    题目实现:网络资源的断点续传功能。 二、解题思路 获取要下载的资源网址 显示网络资源的大小 上次读取到的字节位置以及未读取的字节
  • 你可知HashMap为什么是线程不安全的
    HashMap 的线程不安全 HashMap 的线程不安全主要体现在下面两个方面 在 jdk 1.7 中,当并发执行扩容操作时会造成环形链和数据丢失的情况 在
  • ArrayList的动态扩容机制的介绍

    ArrayList的动态扩容机制的介绍
    对于 ArrayList 的动态扩容机制想必大家都听说过,之前的文章中也谈到过,不过由于时间久远,早已忘却。 所以利用这篇文章做做笔记,加
  • JVM基础之字节码的增强技术介绍

    JVM基础之字节码的增强技术介绍
    字节码增强技术 在上文中,着重介绍了字节码的结构,这为我们了解字节码增强技术的实现打下了基础。字节码增强技术就是一类对现有字
  • Java中的字节码增强技术

    Java中的字节码增强技术
    1.字节码增强技术 字节码增强技术就是一类对现有字节码进行修改或者动态生成全新字节码文件的技术。 参考地址 2.常见技术 技术分类 类
  • Redis BloomFilter布隆过滤器原理与实现

    Redis BloomFilter布隆过滤器原理与实现
    Bloom Filter 概念 布隆过滤器(英语:Bloom Filter)是1970年由一个叫布隆的小伙子提出的。它实际上是一个很长的二进制向量和一系列随机映射
  • Java C++算法题解leetcode801使序列递增的最小交换次

    Java C++算法题解leetcode801使序列递增的最小交换次
    题目要求 思路:状态机DP 实现一:状态机 Java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class Solution { public int minSwap(int[] nums1, int[] nums2) { int n
  • Mybatis结果集映射与生命周期介绍

    Mybatis结果集映射与生命周期介绍
    一、ResultMap结果集映射 1、设计思想 对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了 2、resultMap的应用场
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计