【Spring源码】JDBC数据源访问实现

简介: 我们再来看看阅读线索三,这方面我们从设计模式进行入手。阅读线索三:从这个模块可以学到什么我们看下以下代码,PreparedStatement实例的是由PreparedStatementCreator实现的。再来看看PreparedStatementCreator接口,一共有三个子类实现。也就是说PreparedStatement的三种不同实现被封装到三个子类中,而具体需要哪种实现,只需要传入不同。

一、阅读线索

开始我们今天的对Spring的【模块阅读】,来看看Data Access的JDBC模块是怎么设计的。

在这里插入图片描述

源码阅读前,我们要先思考下本次的阅读线索

  1. JDBC模块有什么作用
  2. 该模块是怎么设计的
  3. 我们从这个模块可以学到什么

二、探索

关于阅读线索一,我们可以很轻松地从官网文档里找到答案。

Data Access with JDBC

也就是提供了数据访问的能力,我们可以使用其来进行各种数据库访问与操作。

先整体看下代码的组织结构,探索下阅读线索二。

在这里插入图片描述

主要分为了4个部分,结合官方文档,我们总结下。

  1. core:包含JdbcTemplate及其各种回调接口。
  2. datasource:包含一个易于DataSource访问的实用程序类和各种简单的DataSource实现。子包embedded提供了对使用 Java 数据库引擎(例如 HSQL、H2 和 Derby)创建嵌入式数据库的支持。
  3. object:包含将 RDBMS 查询、更新和存储过程表示为线程安全、可重用对象的类。
  4. support:提供SQLException 翻译功能和一些实用程序类。

也就是说,核心设计为datasource包提供数据源的访问实现,而core包提供JDBC规范的数据库访问模板

1.数据源访问实现

先来看看datasource是如何实现数据源访问的,既然是要访问,那首先需要初始化,再建立连接

我们定位初始化类DataSourceInitializer的exectute方法。

public class DataSourceInitializer implements InitializingBean, DisposableBean {
   
   

    @Nullable
    private DataSource dataSource;

    /**
     * The {@link DataSource} for the database to populate when this component
     * is initialized and to clean up when this component is shut down.
     * <p>This property is mandatory with no default provided.
     * @param dataSource the DataSource
     */
    public void setDataSource(DataSource dataSource) {
   
   
        this.dataSource = dataSource;
    }

    private void execute(@Nullable DatabasePopulator populator) {
   
   
        Assert.state(this.dataSource != null, "DataSource must be set");
        if (this.enabled && populator != null) {
   
   
            DatabasePopulatorUtils.execute(populator, this.dataSource);
        }
    }
}

发现其实数据源是从外部传入的,可以看到DatabasePopulatorUtils.execute的入参是dataSource

public interface DataSource extends CommonDataSource, Wrapper {
   
   
    Connection getConnection() throws SQLException;

    Connection getConnection(String var1, String var2) throws SQLException;

    PrintWriter getLogWriter() throws SQLException;

    void setLogWriter(PrintWriter var1) throws SQLException;

    void setLoginTimeout(int var1) throws SQLException;

    int getLoginTimeout() throws SQLException;

    default ConnectionBuilder createConnectionBuilder() throws SQLException {
   
   
        throw new SQLFeatureNotSupportedException("createConnectionBuilder not implemented");
    }
}

DataSource对象提供了获取连接的接口,我们来看看是如何获取到连接,从而实现数据源访问的

查看getConnection方法的子类实现

在这里插入图片描述

那获取连接的具体实现应该就在子类AbstractDriverBasedDataSource中。

    /**
     * Getting a Connection using the nasty static from DriverManager is extracted
     * into a protected method to allow for easy unit testing.
     * @see java.sql.DriverManager#getConnection(String, java.util.Properties)
     */
    protected Connection getConnectionFromDriverManager(String url, Properties props) throws SQLException {
   
   
        return DriverManager.getConnection(url, props);
    }

我们最终在AbstractDriverBasedDataSource的调用链上找到了该方法。可以看到是通过传入数据库url和各类参数如密码等来获取连接,从而实现数据源的访问。

2.数据源访问模板

到这我们就完成了线索二的第一部分,我们再看看看线索二的下一部分:

core包提供JDBC规范的数据库访问模板

我们直接找到JdbcTemplate实现类,看下类的组织结构。

在这里插入图片描述

这其中的每一个查询、更新方法就是遵循JDBC规范的模板方法。Spring就是通过这些模板方法来对数据源数据进行操作

到这我们就解决了阅读线索二

jdbc模块的核心设计就是两部分:

  1. 一是实现对数据源的访问连接。
  2. 二是通过JDBC规范的模板对数据源数据进行操作。

三、总结

我们再来看看阅读线索三,这方面我们从设计模式进行入手。

阅读线索三:从这个模块可以学到什么

我们看下以下代码,PreparedStatement实例的是由PreparedStatementCreator实现的。

    @Nullable
    private <T> T execute(PreparedStatementCreator psc, PreparedStatementCallback<T> action, boolean closeResources)
            throws DataAccessException {
   
   

        Assert.notNull(psc, "PreparedStatementCreator must not be null");
        Assert.notNull(action, "Callback object must not be null");
        if (logger.isDebugEnabled()) {
   
   
            String sql = getSql(psc);
            logger.debug("Executing prepared SQL statement" + (sql != null ? " [" + sql + "]" : ""));
        }

        Connection con = DataSourceUtils.getConnection(obtainDataSource());
        PreparedStatement ps = null;
        try {
   
   
            ps = psc.createPreparedStatement(con);
            applyStatementSettings(ps);
            T result = action.doInPreparedStatement(ps);
            handleWarnings(ps);
            return result;
        }
        ......
}

再来看看PreparedStatementCreator接口,一共有三个子类实现

@FunctionalInterface
public interface PreparedStatementCreator {
   
   

    /**
     * Create a statement in this connection. Allows implementations to use
     * PreparedStatements. The JdbcTemplate will close the created statement.
     * @param con the connection used to create statement
     * @return a prepared statement
     * @throws SQLException there is no need to catch SQLExceptions
     * that may be thrown in the implementation of this method.
     * The JdbcTemplate class will handle them.
     */
    PreparedStatement createPreparedStatement(Connection con) throws SQLException;

}

在这里插入图片描述

也就是说PreparedStatement的三种不同实现被封装到三个子类中,而具体需要哪种实现,只需要传入不同的PreparedStatementCreator实现即可。

这种把不同实现封装起来,需要哪种实现由行为模式决定,也就是入参决定,这种模式被称为策略模式

createPreparedStatement接口也称为策略接口

未完待续。。。

好了,今天的分享就到这📚。大家能否感受到通过按【模块阅读】这种方式来阅读源码的乐趣呢

创作不易,不妨点赞、收藏、关注支持一下,各位的支持就是我创作的最大动力❤️

相关文章
|
19天前
|
Java 应用服务中间件 Nacos
Spring Cloud 常用各个组件详解及实现原理(附加源码+实现逻辑图)
Spring Cloud 常用各个组件详解及实现原理(附加源码+实现逻辑图)
31 0
|
23天前
|
监控 数据可视化 安全
一套成熟的Spring Cloud智慧工地平台源码,自主版权,开箱即用
这是一套基于Spring Cloud的智慧工地管理平台源码,具备自主版权,易于使用。平台运用现代技术如物联网、大数据等改进工地管理,服务包括建设各方,提供人员、车辆、视频监控等七大维度的管理。特色在于可视化管理、智能报警、移动办公和分布计算存储。功能涵盖劳务实名制管理、智能考勤、视频监控AI识别、危大工程监控、环境监测、材料管理和进度管理等,实现工地安全、高效的智慧化管理。
|
1天前
|
监控 Java 应用服务中间件
Spring Boot 源码面试知识点
【5月更文挑战第12天】Spring Boot 是一个强大且广泛使用的框架,旨在简化 Spring 应用程序的开发过程。深入了解 Spring Boot 的源码,有助于开发者更好地使用和定制这个框架。以下是一些关键的知识点:
12 6
|
2天前
|
Java 应用服务中间件 测试技术
深入探索Spring Boot Web应用源码及实战应用
【5月更文挑战第11天】本文将详细解析Spring Boot Web应用的源码架构,并通过一个实际案例,展示如何构建一个基于Spring Boot的Web应用。本文旨在帮助读者更好地理解Spring Boot的内部工作机制,以及如何利用这些机制优化自己的Web应用开发。
11 3
|
4天前
|
存储 前端开发 Java
Spring Boot自动装配的源码学习
【4月更文挑战第8天】Spring Boot自动装配是其核心机制之一,其设计目标是在应用程序启动时,自动配置所需的各种组件,使得应用程序的开发和部署变得更加简单和高效。下面是关于Spring Boot自动装配的源码学习知识点及实战。
13 1
|
6天前
|
传感器 人工智能 前端开发
JAVA语言VUE2+Spring boot+MySQL开发的智慧校园系统源码(电子班牌可人脸识别)Saas 模式
智慧校园电子班牌,坐落于班级的门口,适合于各类型学校的场景应用,班级学校日常内容更新可由班级自行管理,也可由学校统一管理。让我们一起看看,电子班牌有哪些功能呢?
47 4
JAVA语言VUE2+Spring boot+MySQL开发的智慧校园系统源码(电子班牌可人脸识别)Saas 模式
|
7天前
|
Java Spring
spring boot访问接口报500
spring boot访问接口报500
12 2
|
13天前
|
设计模式 安全 Java
【初学者慎入】Spring源码中的16种设计模式实现
以上是威哥给大家整理了16种常见的设计模式在 Spring 源码中的运用,学习 Spring 源码成为了 Java 程序员的标配,你还知道Spring 中哪些源码中运用了设计模式,欢迎留言与威哥交流。
|
18天前
|
XML 人工智能 Java
Spring Bean名称生成规则(含源码解析、自定义Spring Bean名称方式)
Spring Bean名称生成规则(含源码解析、自定义Spring Bean名称方式)
|
24天前
|
Java Maven Nacos
Spring Cloud Eureka 服务注册和服务发现超详细(附加--源码实现案例--及实现逻辑图)
Spring Cloud Eureka 服务注册和服务发现超详细(附加--源码实现案例--及实现逻辑图)
31 0