如果你已经使用了一段时间的Spring Boot,你可能对使用属性设置连接细节(connection details)很熟悉。例如,你可能已经使用 spring.datasource.url
来配置JDBC连接。在Spring Boot 3.1中,这仍然像你所期望的那样工作,但我们在底层做了一些改变,将自动配置与属性解耦。
现在有一个新的 ConnectionDetails
抽象。这个接口模拟了连接到远程服务的概念。如果你看一下这个接口,你会发现它是空的。它作为一个标记接口,并由其他多个接口扩展,这些接口对具体的远程服务的连接进行建模,例如,RedisConnectionDetails
用于与 Redis server 的连接,JdbcConnectionDetails
用于通过JDBC与数据库服务器的连接。
我们添加 ConnectionDetails
抽象主要是为了支持我们全新的Docker Compose和Testcontainers功能,我们将在随后的博客文章中深入介绍。但这个抽象并不只限于Docker Compose或Testcontainers。Spring Boot中的自动配置已经改为使用 ConnectionDetails
,如果它们可用的话。在这种情况下,它们甚至会优先于配置属性。如果没有这样的 ConnectionDetails
Bean,那么就会使用 properties 。
让我们来看看 JdbcConnectionDetails
接口:
COPYpublic interface JdbcConnectionDetails extends ConnectionDetails {
String getUsername();
String getPassword();
String getJdbcUrl();
}
这是 Spring Boot 需要知道的所有信息,以便连接到JDBC数据库。URL包含要使用的JDBC驱动程序、要连接的主机、要使用的端口等。用户名和密码是认证所需的。这相当于设置 spring.datasource.url
、spring.datasource.username
和 spring.datasource.password
属性。
请注意,该接口并不包括与JDBC连接有关的所有方法。例如,连接池的配置不是其中的一部分。这个接口只处理连接到远程服务所需的信息,其他的关注点,如池的大小等,仍然通过 properties 来配置。
这种抽象很有用,因为在未来的某个时候,可以在它的基础上建立其他有趣的集成。例如,在 VMware Tanzu cloud 中运行的Spring Boot应用程序可以发现与该应用程序相关的数据库,并自动提供一个 JdbcConnectionDetails
(或 R2dbcConnectionDetails
,用于响应式应用程序)bean,该bean知道如何连接到该数据库。对于用户来说,这意味着减少了折腾 Kubernetes config maps 和 secrets 的时间,因为应用程序 “知道” 如何连接到数据库。你将有更多的时间专注于其他重要的事情,如解决业务问题。
你可能会想,既然已经可以为连接细节贡献属性了,为什么还需要一个新的接口。事实上,在 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数据库。
在撰写本文时,有以下子接口:
-
CassandraConnectionDetails
用于与 Cassandra server 的连接。 -
CouchbaseConnectionDetails
用于与 Couchbase server 的连接 -
ElasticsearchConnectionDetails
用于与 Elasticsearch server 的连接 -
JdbcConnectionDetails
用于通过 JDBC 与 database server 的连接。 -
KafkaConnectionDetails
用于与 Kafka server 的连接 -
MongoConnectionDetails
用于与 MongoDB server 的连接 -
Neo4jConnectionDetails
用于与 Neo4J server 的连接 -
R2dbcConnectionDetails
用于通过 R2DBC 与 database server 的连接。 -
RabbitConnectionDetails
用于与 RabbitMQ server 的连接 -
RedisConnectionDetails
用于与 Redis server 的连接 -
ZipkinConnectionDetails
用于与 Zipkin server的连接