此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Boot 3.4.3spring-doc.cadn.net.cn

开发时服务

开发时服务提供在开发应用程序时运行应用程序所需的外部依赖项。 它们只应在开发时使用,并在部署应用程序时禁用。spring-doc.cadn.net.cn

Spring Boot 支持两种开发时服务,即 Docker Compose 和 Testcontainers。 接下来的部分将提供有关它们的更多详细信息。spring-doc.cadn.net.cn

Docker Compose 支持

Docker Compose 是一种流行的技术,可用于为应用程序所需的服务定义和管理多个容器。 一个compose.yml文件通常在定义和配置服务容器的应用程序旁边创建。spring-doc.cadn.net.cn

Docker Compose 的典型工作流是运行docker compose up,在应用程序连接到已启动的服务的情况下处理应用程序,然后运行docker compose down当你完成时。spring-doc.cadn.net.cn

spring-boot-docker-compose模块可以包含在项目中,以支持使用 Docker Compose 处理容器。 将模块依赖项添加到您的构建中,如以下 Maven 和 Gradle 清单所示:spring-doc.cadn.net.cn

Maven 系列
<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-docker-compose</artifactId>
		<optional>true</optional>
	</dependency>
</dependencies>
Gradle
dependencies {
	developmentOnly("org.springframework.boot:spring-boot-docker-compose")
}

当此模块作为依赖项包含在内时, Spring Boot 将执行以下作:spring-doc.cadn.net.cn

如果在启动应用程序时 Docker Compose 服务已经在运行,则 Spring Boot 将仅为每个支持的容器创建服务连接 bean。 它不会调用docker compose up,它不会调用docker compose stop当应用程序关闭时。spring-doc.cadn.net.cn

默认情况下,重新打包的存档不包含 Spring Boot 的 Docker Compose。 如果您想使用此支持,则需要包含它。 使用 Maven 插件时,将excludeDockerComposeproperty 设置为false. 使用 Gradle 插件时,配置任务的 Classpath 以包含developmentOnly配置.

先决条件

您需要具有dockerdocker compose(或docker-compose) CLI 应用程序。 支持的最低 Docker Compose 版本为 2.2.0。spring-doc.cadn.net.cn

服务连接

服务连接是与任何远程服务的连接。 Spring Boot 的自动配置可以使用服务连接的详细信息,并使用它们来建立与远程服务的连接。 执行此作时,连接详细信息优先于任何与连接相关的配置属性。spring-doc.cadn.net.cn

当使用 Spring Boot 的 Docker Compose 支持时,将建立与容器映射的端口的服务连接。spring-doc.cadn.net.cn

Docker Compose 的使用方式通常是将容器内的端口映射到计算机上的临时端口。 例如,Postgres 服务器可以使用端口 5432 在容器内运行,但在本地映射到完全不同的端口。 服务连接将始终发现并使用本地映射的端口。

使用容器的映像名称建立服务连接。 目前支持以下服务连接:spring-doc.cadn.net.cn

连接详细信息 匹配时间

ActiveMQConnectionDetailsspring-doc.cadn.net.cn

名为 “symptoma/activemq” 或 “apache/activemq-classic” 的容器spring-doc.cadn.net.cn

ArtemisConnectionDetailsspring-doc.cadn.net.cn

名为 “apache/activemq-artemis” 的容器spring-doc.cadn.net.cn

CassandraConnectionDetailsspring-doc.cadn.net.cn

名为 “cassandra” 或 “bitnami/cassandra” 的容器spring-doc.cadn.net.cn

ElasticsearchConnectionDetailsspring-doc.cadn.net.cn

名为 “elasticsearch” 或 “bitnami/elasticsearch” 的容器spring-doc.cadn.net.cn

HazelcastConnectionDetailsspring-doc.cadn.net.cn

名为 “hazelcast/hazelcast” 的容器。spring-doc.cadn.net.cn

JdbcConnectionDetailsspring-doc.cadn.net.cn

名为“clickhouse/clickhouse-server”、“bitnami/clickhouse”、“gvenzl/oracle-free”、“gvenzl/oracle-xe”、“mariadb”、“bitnami/mariadb”、“mssql/server”、“mysql”、“bitnami/mysql”、“postgres”或“bitnami/postgresql”的容器spring-doc.cadn.net.cn

LdapConnectionDetailsspring-doc.cadn.net.cn

名为 “osixia/openldap” 和 “lldap/lldap” 的容器spring-doc.cadn.net.cn

MongoConnectionDetailsspring-doc.cadn.net.cn

名为 “mongo” 或 “bitnami/mongodb” 的容器spring-doc.cadn.net.cn

Neo4jConnectionDetailsspring-doc.cadn.net.cn

名为 “neo4j” 或 “bitnami/neo4j” 的容器spring-doc.cadn.net.cn

OtlpLoggingConnectionDetailsspring-doc.cadn.net.cn

名为 “otel/opentelemetry-collector-contrib” 和 “grafana/otel-lgtm” 的容器spring-doc.cadn.net.cn

OtlpMetricsConnectionDetailsspring-doc.cadn.net.cn

名为 “otel/opentelemetry-collector-contrib” 和 “grafana/otel-lgtm” 的容器spring-doc.cadn.net.cn

OtlpTracingConnectionDetailsspring-doc.cadn.net.cn

名为 “otel/opentelemetry-collector-contrib” 和 “grafana/otel-lgtm” 的容器spring-doc.cadn.net.cn

PulsarConnectionDetailsspring-doc.cadn.net.cn

名为 “apachepulsar/pulsar” 的容器spring-doc.cadn.net.cn

R2dbcConnectionDetailsspring-doc.cadn.net.cn

名为“clickhouse/clickhouse-server”、“bitnami/clickhouse”、“gvenzl/oracle-free”、“gvenzl/oracle-xe”、“mariadb”、“bitnami/mariadb”、“mssql/server”、“mysql”、“bitnami/mysql”、“postgres”或“bitnami/postgresql”的容器spring-doc.cadn.net.cn

RabbitConnectionDetailsspring-doc.cadn.net.cn

名为 “rabbitmq” 或 “bitnami/rabbitmq” 的容器spring-doc.cadn.net.cn

RedisConnectionDetailsspring-doc.cadn.net.cn

名为 “redis”、“bitnami/redis”、“redis/redis-stack” 或 “redis/redis-stack-server” 的容器spring-doc.cadn.net.cn

ZipkinConnectionDetailsspring-doc.cadn.net.cn

名为 “openzipkin/zipkin” 的容器。spring-doc.cadn.net.cn

SSL 支持

某些映像开箱即用地启用了 SSL,或者您可能希望为容器启用 SSL 以镜像您的生产设置。 Spring Boot 支持对支持的服务连接进行 SSL 配置。 请注意,您仍然需要自己在容器内运行的服务上启用 SSL,此功能仅在应用程序的客户端配置 SSL。spring-doc.cadn.net.cn

以下服务连接支持 SSL:spring-doc.cadn.net.cn

要为服务启用 SSL 支持,您可以使用服务标签spring-doc.cadn.net.cn

对于基于 JKS 的密钥库和信任库,您可以使用以下容器标签:spring-doc.cadn.net.cn

这些标签反映了 SSL 捆绑包的可用属性。spring-doc.cadn.net.cn

对于基于 PEM 的密钥库和信任库,您可以使用以下容器标签:spring-doc.cadn.net.cn

这些标签反映了 SSL 捆绑包的可用属性。spring-doc.cadn.net.cn

以下示例为 redis 容器启用 SSL:spring-doc.cadn.net.cn

services:
  redis:
    image: 'redis:latest'
    ports:
      - '6379'
    secrets:
      - ssl-ca
      - ssl-key
      - ssl-cert
    command: 'redis-server --tls-port 6379 --port 0 --tls-cert-file /run/secrets/ssl-cert --tls-key-file /run/secrets/ssl-key --tls-ca-cert-file /run/secrets/ssl-ca'
    labels:
      - 'org.springframework.boot.sslbundle.pem.keystore.certificate=client.crt'
      - 'org.springframework.boot.sslbundle.pem.keystore.private-key=client.key'
      - 'org.springframework.boot.sslbundle.pem.truststore.certificate=ca.crt'
secrets:
  ssl-ca:
    file: 'ca.crt'
  ssl-key:
    file: 'server.key'
  ssl-cert:
    file: 'server.crt'

自定义图像

有时,您可能需要使用自己的映像版本来提供服务。 您可以使用任何自定义映像,只要其行为方式与标准映像相同即可。 具体而言,标准映像支持的任何环境变量也必须在自定义映像中使用。spring-doc.cadn.net.cn

如果您的图像使用不同的名称,您可以在compose.yml文件,以便 Spring Boot 可以提供服务连接。 使用名为org.springframework.boot.service-connection以提供服务名称。spring-doc.cadn.net.cn

services:
  redis:
    image: 'mycompany/mycustomredis:7.0'
    ports:
      - '6379'
    labels:
      org.springframework.boot.service-connection: redis

跳过特定容器

如果您在compose.yml,则不希望连接到您的应用程序,则可以使用标签来忽略它。 任何标有org.springframework.boot.ignore将被 Spring Boot 忽略。spring-doc.cadn.net.cn

services:
  redis:
    image: 'redis:7.0'
    ports:
      - '6379'
    labels:
      org.springframework.boot.ignore: true

使用特定的 Compose 文件

如果您的 compose 文件与应用程序不在同一目录中,或者名称不同,则可以使用spring.docker.compose.fileapplication.propertiesapplication.yaml以指向其他文件。 属性可以定义为精确路径或相对于应用程序的路径。spring-doc.cadn.net.cn

spring.docker.compose.file=../my-compose.yml
spring:
  docker:
    compose:
      file: "../my-compose.yml"

等待容器就绪

由 Docker Compose 启动的容器可能需要一些时间才能完全准备就绪。 检查就绪情况的推荐方法是添加healthcheck部分compose.yml文件。spring-doc.cadn.net.cn

由于这种情况并不少见healthcheck要省略的配置compose.yml文件,Spring Boot 还会直接检查服务就绪情况。 默认情况下,当可以与容器的映射端口建立 TCP/IP 连接时,容器被视为准备就绪。spring-doc.cadn.net.cn

您可以通过添加org.springframework.boot.readiness-check.tcp.disable标签中的compose.yml文件。spring-doc.cadn.net.cn

services:
  redis:
    image: 'redis:7.0'
    ports:
      - '6379'
    labels:
      org.springframework.boot.readiness-check.tcp.disable: true

您还可以在application.propertiesapplication.yaml文件:spring-doc.cadn.net.cn

spring.docker.compose.readiness.tcp.connect-timeout=10s
spring.docker.compose.readiness.tcp.read-timeout=5s
spring:
  docker:
    compose:
      readiness:
        tcp:
          connect-timeout: 10s
          read-timeout: 5s

总超时可以使用spring.docker.compose.readiness.timeout.spring-doc.cadn.net.cn

控制 Docker Compose 生命周期

默认情况下,Spring Boot 调用docker compose up当您的应用程序启动时,以及docker compose stop当它关闭时。 如果您希望使用不同的生命周期管理,可以使用spring.docker.compose.lifecycle-management财产。spring-doc.cadn.net.cn

支持以下值:spring-doc.cadn.net.cn

此外,您还可以使用spring.docker.compose.start.command属性来更改docker compose updocker compose start被使用。 这spring.docker.compose.stop.command允许您配置 ifdocker compose downdocker compose stop被使用。spring-doc.cadn.net.cn

以下示例显示了如何配置生命周期管理:spring-doc.cadn.net.cn

spring.docker.compose.lifecycle-management=start-and-stop
spring.docker.compose.start.command=start
spring.docker.compose.stop.command=down
spring.docker.compose.stop.timeout=1m
spring:
  docker:
    compose:
      lifecycle-management: start-and-stop
      start:
        command: start
      stop:
        command: down
        timeout: 1m

激活 Docker Compose 配置文件

Docker Compose 配置文件与 Spring 配置文件类似,因为它们允许您针对特定环境调整 Docker Compose 配置。 如果要激活特定的 Docker Compose 配置文件,可以使用spring.docker.compose.profiles.active属性包含在application.propertiesapplication.yaml文件:spring-doc.cadn.net.cn

spring.docker.compose.profiles.active=myprofile
spring:
  docker:
    compose:
      profiles:
        active: "myprofile"

在测试中使用 Docker Compose

默认情况下,Spring Boot 的 Docker Compose 支持在运行测试时处于禁用状态。spring-doc.cadn.net.cn

要在测试中启用 Docker Compose 支持,请将 Docker Compose 的spring.docker.compose.skip.in-testsfalse.spring-doc.cadn.net.cn

使用 Gradle 时,您还需要更改spring-boot-docker-composedependency from (依赖项)developmentOnlytestAndDevelopmentOnly:spring-doc.cadn.net.cn

Gradle
dependencies {
	testAndDevelopmentOnly("org.springframework.boot:spring-boot-docker-compose")
}

Testcontainers 支持

除了使用 Testcontainers 进行集成测试外,还可以在开发时使用它们。 接下来的部分将提供有关这方面的更多详细信息。spring-doc.cadn.net.cn

在开发时使用 Testcontainers

这种方法允许开发人员为应用程序所依赖的服务快速启动容器,无需手动预置数据库服务器等内容。 以这种方式使用 Testcontainers 可提供类似于 Docker Compose 的功能,但您的容器配置是 Java 而不是 YAML。spring-doc.cadn.net.cn

要在开发时使用 Testcontainers,您需要使用 “test” classpath 而不是 “main” 来启动应用程序。 这将允许您访问所有声明的测试依赖项,并为您提供一个自然的位置来编写测试配置。spring-doc.cadn.net.cn

要创建应用程序的测试可启动版本,您应该在src/test目录。 例如,如果您的主应用程序位于src/main/java/com/example/MyApplication.java,您应该创建src/test/java/com/example/TestMyApplication.javaspring-doc.cadn.net.cn

TestMyApplication类可以使用SpringApplication.from(…​)启动真实应用程序的方法:spring-doc.cadn.net.cn

import org.springframework.boot.SpringApplication;

public class TestMyApplication {

	public static void main(String[] args) {
		SpringApplication.from(MyApplication::main).run(args);
	}

}

You’ll also need to define the Container instances that you want to start along with your application. To do this, you need to make sure that the spring-boot-testcontainers module has been added as a test dependency. Once that has been done, you can create a @TestConfiguration class that declares @Bean methods for the containers you want to start.spring-doc.cadn.net.cn

You can also annotate your @Bean methods with @ServiceConnection in order to create ConnectionDetails beans. See the service connections section for details of the supported technologies.spring-doc.cadn.net.cn

A typical Testcontainers configuration would look like this:spring-doc.cadn.net.cn

import org.testcontainers.containers.Neo4jContainer;

import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.context.annotation.Bean;

@TestConfiguration(proxyBeanMethods = false)
public class MyContainersConfiguration {

	@Bean
	@ServiceConnection
	public Neo4jContainer<?> neo4jContainer() {
		return new Neo4jContainer<>("neo4j:5");
	}

}
The lifecycle of Container beans is automatically managed by Spring Boot. Containers will be started and stopped automatically.
You can use the spring.testcontainers.beans.startup property to change how containers are started. By default sequential startup is used, but you may also choose parallel if you wish to start multiple containers in parallel.

Once you have defined your test configuration, you can use the with(…​) method to attach it to your test launcher:spring-doc.cadn.net.cn

import org.springframework.boot.SpringApplication;

public class TestMyApplication {

	public static void main(String[] args) {
		SpringApplication.from(MyApplication::main).with(MyContainersConfiguration.class).run(args);
	}

}

You can now launch TestMyApplication as you would any regular Java main method application to start your application and the containers that it needs to run.spring-doc.cadn.net.cn

You can use the Maven goal spring-boot:test-run or the Gradle task bootTestRun to do this from the command line.

Contributing Dynamic Properties at Development Time

If you want to contribute dynamic properties at development time from your Container @Bean methods, define an additional DynamicPropertyRegistrar bean. The registrar should be defined using a @Bean method that injects the container from which the properties will be sourced as a parameter. This arrangement ensures that container has been started before the properties are used.spring-doc.cadn.net.cn

A typical configuration would look like this:spring-doc.cadn.net.cn

import org.testcontainers.containers.MongoDBContainer;

import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.test.context.DynamicPropertyRegistrar;

@TestConfiguration(proxyBeanMethods = false)
public class MyContainersConfiguration {

	@Bean
	public MongoDBContainer mongoDbContainer() {
		return new MongoDBContainer("mongo:5.0");
	}

	@Bean
	public DynamicPropertyRegistrar mongoDbProperties(MongoDBContainer container) {
		return (properties) -> {
			properties.add("spring.data.mongodb.host", container::getHost);
			properties.add("spring.data.mongodb.port", container::getFirstMappedPort);
		};
	}

}
Using a @ServiceConnection is recommended whenever possible, however, dynamic properties can be a useful fallback for technologies that don’t yet have @ServiceConnection support.

Importing Testcontainers Declaration Classes

A common pattern when using Testcontainers is to declare Container instances as static fields. Often these fields are defined directly on the test class. They can also be declared on a parent class or on an interface that the test implements.spring-doc.cadn.net.cn

For example, the following MyContainers interface declares mongo and neo4j containers:spring-doc.cadn.net.cn

import org.testcontainers.containers.MongoDBContainer;
import org.testcontainers.containers.Neo4jContainer;
import org.testcontainers.junit.jupiter.Container;

import org.springframework.boot.testcontainers.service.connection.ServiceConnection;

public interface MyContainers {

	@Container
	@ServiceConnection
	MongoDBContainer mongoContainer = new MongoDBContainer("mongo:5.0");

	@Container
	@ServiceConnection
	Neo4jContainer<?> neo4jContainer = new Neo4jContainer<>("neo4j:5");

}

If you already have containers defined in this way, or you just prefer this style, you can import these declaration classes rather than defining your containers as @Bean methods. To do so, add the @ImportTestcontainers annotation to your test configuration class:spring-doc.cadn.net.cn

import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.testcontainers.context.ImportTestcontainers;

@TestConfiguration(proxyBeanMethods = false)
@ImportTestcontainers(MyContainers.class)
public class MyContainersConfiguration {

}
If you don’t intend to use the service connections feature but want to use @DynamicPropertySource instead, remove the @ServiceConnection annotation from the Container fields. You can also add @DynamicPropertySource annotated methods to your declaration class.

Using DevTools with Testcontainers at Development Time

When using devtools, you can annotate beans and bean methods with @RestartScope. Such beans won’t be recreated when the devtools restart the application. This is especially useful for Container beans, as they keep their state despite the application restart.spring-doc.cadn.net.cn

import org.testcontainers.containers.MongoDBContainer;

import org.springframework.boot.devtools.restart.RestartScope;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.context.annotation.Bean;

@TestConfiguration(proxyBeanMethods = false)
public class MyContainersConfiguration {

	@Bean
	@RestartScope
	@ServiceConnection
	public MongoDBContainer mongoDbContainer() {
		return new MongoDBContainer("mongo:5.0");
	}

}
If you’re using Gradle and want to use this feature, you need to change the configuration of the spring-boot-devtools dependency from developmentOnly to testAndDevelopmentOnly. With the default scope of developmentOnly, the bootTestRun task will not pick up changes in your code, as the devtools are not active.