Spring Boot 3.1 的 ConnectionDetails 抽象

工程 | Moritz Halbritter | 2023年6月19日 | ...

如果您使用 Spring Boot 一段时间了,您可能熟悉使用属性设置连接详细信息。例如,您可能使用过 spring.datasource.url 来配置 JDBC 连接。在 Spring Boot 3.1 中,这将继续按预期工作,但我们在底层做了一些更改,以将自动配置与属性解耦。

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

我们添加 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 配置映射和密钥的时间,因为应用程序“知道”如何连接到数据库。您将有更多时间专注于生活中重要的事情,例如解决业务问题和参加冲刺会议!

您可能想知道,当已经可以为连接详细信息提供属性时,为什么需要一个新的接口。实际上,在 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 社区中所有即将举行的活动。

查看全部