Spring Boot 3.1 的 ConnectionDetails 抽象

工程 | 莫里茨·哈尔布里特 | 2023 年 6 月 19 日 | ...

如果您使用 Spring Boot 有一段时间了,您可能熟悉通过属性设置连接详细信息。例如,您可能使用 spring.datasource.url 来配置 JDBC 连接。在 Spring Boot 3.1 中,这种情况会像您期望的那样继续,但我们在底层进行了一些更改,以解耦自动配置和属性。

现在有一个新的 ConnectionDetails 抽象。这个接口模拟了到远程服务的连接概念。如果您查看这个接口,您会发现它是空的。它作为一个标记接口,并被多个其他接口扩展,这些接口模拟了到具体远程服务的连接,例如,连接到 Redis 服务器RedisConnectionDetails 或通过 JDBC 连接到数据库服务器的 JdbcConnectionDetails

我们添加 ConnectionDetails 抽象主要是为了支持我们全新的 Docker Compose 和 Testcontainers 功能,这些功能将在后续的博客文章中深入介绍。但是,此抽象不仅限于 Docker Compose 或 Testcontainers。Spring Boot 中的自动配置已更改为在可用时使用 ConnectionDetails。在这种情况下,它们将优先于配置属性。如果没有这样的 ConnectionDetails bean,则将使用属性。

让我们看一下 JdbcConnectionDetails 接口

public interface JdbcConnectionDetails extends ConnectionDetails {

  String getUsername();

  String getPassword();

  String getJdbcUrl();

}

这是 Spring Boot 连接 JDBC 数据库所需的所有信息。URL 包含要使用的 JDBC 驱动程序、要连接的主机、要使用的端口等。用户名和密码用于身份验证。这等同于设置 spring.datasource.urlspring.datasource.usernamespring.datasource.password 属性。

请注意,该接口不包含与 JDBC 连接相关的所有方法。例如,连接池配置不属于其协议。此接口仅处理连接到远程服务所需的信息,其他事项(如池大小等)仍通过属性进行配置。

此抽象很有用,因为在未来,可以在其之上构建其他有趣的集成。例如,运行在 VMware Tanzu 云上的 Spring Boot 应用程序可以发现与该应用程序关联的数据库,并自动提供一个 JdbcConnectionDetails(或响应式应用程序的 R2dbcConnectionDetails)bean,该 bean 知道如何连接到该数据库。对您用户而言,这意味着减少在 Kubernetes ConfigMaps 和 Secrets 上浪费时间,因为应用程序“仅仅知道”如何连接到数据库。您将有更多时间专注于生活中的重要事情,例如解决业务问题和参加 Sprint 会议!

您可能想知道,当已经可以贡献连接详细信息的属性时,为什么还需要一个新的接口。确实,在 application.properties 之外使用连接属性是很常见的。例如,在使用 Testcontainers 编写集成测试时,经常使用 @DynamicPropertySource 功能。

在应用程序配置之外使用属性的问题在于它们可能会发生变化(并且过去也发生过变化,例如 spring.redis 属性),这会导致脆弱的耦合。如果属性名称更改,设置这些属性的代码仍然可以编译,因为它们都是“字符串化”键入的。当使用 ConnectionDetails 来提供如何连接到远程服务的信息时,如果我们进行向后不兼容的更改(我们不会轻易更改,承诺!),这将导致编译错误。这比在生产环境中发现中断要好得多。

如果您想自己使用 ConnectionsDetails 抽象,您需要做的就是定义一个具有正确类型的 bean,例如

@Configuration(proxyBeanMethods = false)
class MyConnectionDetailsConfiguration {

  @Bean
  JdbcConnectionDetails myJdbcConnectionDetails() {
    return new JdbcConnectionDetails() {

      @Override
      public String getUsername() {
        return "myuser";
      }

      @Override
      public String getPassword() {
        return "3xtr3mly-s3cr3t";
      }

      @Override
      public String getJdbcUrl() {
        return "jdbc:postgresql://postgres-server.svc.local:5432/mydatabase?ssl=true&sslmode=required";
      }

    };
  }

}

现在,Spring Boot 将自动使用这些信息连接到给定的 PostgreSQL 数据库。

在撰写本文时,有以下子接口

我们希望您喜欢我们对 ConnectionDetails 抽象的简短介绍,并且我们很期待看到在其之上构建的精彩内容!

获取 Spring 新闻通讯

通过 Spring 新闻通讯保持联系

订阅

领先一步

VMware 提供培训和认证,助您加速进步。

了解更多

获得支持

Tanzu Spring 提供 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件,只需一份简单的订阅。

了解更多

即将举行的活动

查看 Spring 社区所有即将举行的活动。

查看所有