文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2024-04-02 19:55

关注

一、重点概念

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的相关配置如下,我们梳理一下这个类生效的条件

这里我们介绍一下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数据源配置内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯