升到 Spring Boot 4.2.0-RC1,Docker Compose 里想给 MySQL 开随机 root 密码、给 RabbitMQ 设非默认 vhost。Service Connection 到底吃哪组账号、virtual-host 会不会还停在 /?结论先说:随机 root 时 Boot 用的是 MYSQL_USER/MYSQL_PASSWORD 这组业务账号去拼 JDBC;只写 MYSQL_RANDOM_ROOT_PASSWORD、不配业务用户,启动直接 IllegalStateException。Rabbit 侧 RABBITMQ_DEFAULT_VHOST 会进 RabbitConnectionDetails 和 CachingConnectionFactory,连接 URI 里能看到非默认 vhost。
Spring Boot 4.2.0-RC1 Release Notes 写明了这两条:MariaDB/MySQL Docker Compose 支持随机 root 密码;RabbitMQ Docker Compose 支持 RABBITMQ_DEFAULT_VHOST。环境是 JDK 21.0.12.1、Boot 4.2.0-RC1,镜像 mysql:8.4 与 rabbitmq:3.13-management。
依赖带上 JDBC、RabbitMQ 和 docker-compose 模块:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-rabbitmq</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-docker-compose</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
compose.yaml 里 MySQL 开随机 root,同时给出业务库账号;Rabbit 设 RABBITMQ_DEFAULT_VHOST=demo:
services:
mysql:
image: mysql:8.4
environment:
MYSQL_DATABASE: demodb
MYSQL_USER: appuser
MYSQL_PASSWORD: app-secret-42
MYSQL_RANDOM_ROOT_PASSWORD: "yes"
ports:
- "3306"
rabbitmq:
image: rabbitmq:3.13-management
environment:
RABBITMQ_DEFAULT_USER: app
RABBITMQ_DEFAULT_PASS: rabbit-secret-42
RABBITMQ_DEFAULT_VHOST: demo
ports:
- "5672"
- "15672"
容器环境里 MYSQL_ROOT_PASSWORD 未设置,MYSQL_RANDOM_ROOT_PASSWORD=yes;Rabbit 的 vhost 是 demo。Boot 启动后拉起 Compose,MySQL / Rabbit 报 Healthy,约 13 秒进业务代码:
2026-10-29T08:15:22.065+08:00 INFO ... DockerComposeLifecycleManager : Using Docker Compose file compose.yaml
2026-10-29T08:15:28.883+08:00 INFO ... DockerCli : Container boot42-rc1-compose-root-vhost-rabbitmq-1 Healthy
2026-10-29T08:15:33.887+08:00 INFO ... DockerCli : Container boot42-rc1-compose-root-vhost-mysql-1 Healthy
2026-10-29T08:15:35.130+08:00 INFO ... ComposeRootVhostDemo : Started ComposeRootVhostDemo in 13.316 seconds (process running for 13.514)
JdbcConnectionDetails 拿到的不是 root,而是业务用户;密码与 MYSQL_PASSWORD 一致(日志里脱敏):
jdbc.url=jdbc:mysql://127.0.0.1:32768/demodb
jdbc.username=appuser
jdbc.password.present=true
jdbc.password.length=13
jdbc.password.masked=ap****42
jdbc.password.equals.app-secret=true
jdbc.username.equals.appuser=true
ASSERT notUsingRootUser=true
jdbc.query.ok=1
jdbc.query.database=demodb
jdbc.query.user=appuser@172.18.0.1
ASSERT jdbcConnected=true
Hikari 能建连,SELECT 1 返回 1,当前库 demodb、会话用户 appuser@...。如果升级后仍假定 MYSQL_ROOT_PASSWORD=root 去手写 datasource,和 Service Connection 实际注入的业务账号会对不上;随机 root 场景下 root 口令本就不该进应用配置。
Rabbit 一侧,RabbitConnectionDetails.getVirtualHost() 与 CachingConnectionFactory.getVirtualHost() 都是 demo,不是默认 /。建连日志里的 delegate URI 也带上了 /demo:
rabbit.username=app
rabbit.password.present=true
rabbit.password.masked=ra****42
rabbit.virtualHost=demo
ASSERT rabbitVirtualHostIsDemo=true
ASSERT rabbitVirtualHostNotDefaultSlash=true
cachingConnectionFactory.virtualHost=demo
cachingConnectionFactory.host=127.0.0.1
cachingConnectionFactory.port=32770
ASSERT factoryVirtualHostIsDemo=true
2026-10-29T08:15:35.387+08:00 INFO ... CachingConnectionFactory : Created new connection: rabbitConnectionFactory#60c73e58:0/SimpleConnection@1f4f0fcc [delegate=amqp://app@127.0.0.1:32770/demo, localPort=39514]
rabbit.connection.open=true
ASSERT rabbitConnected=true
RC1 在 RabbitMqEnvironment 里读 RABBITMQ_DEFAULT_VHOST(或 RABBITMQ_VHOST),缺省才回落 /。应用若仍按默认 vhost 声明队列、绑定,连上 Broker 后会落到错误虚机,权限和资源都对不上。
只开随机 root、不配业务用户时,Compose 容器能起来,Boot 在装配 Service Connection 时失败:
2026-10-29T08:15:52.993+08:00 ERROR ... SpringApplication : Application run failed
java.lang.IllegalStateException: MYSQL_RANDOM_ROOT_PASSWORD is not supported without MYSQL_USER and MYSQL_PASSWORD
at org.springframework.util.Assert.state(Assert.java:80)
at org.springframework.boot.jdbc.docker.compose.MySqlEnvironment.extractPassword(MySqlEnvironment.java:42)
MySqlEnvironment(MariaDB 对应 MariaDbEnvironment)要求:出现 MYSQL_RANDOM_ROOT_PASSWORD / MARIADB_RANDOM_ROOT_PASSWORD 时,必须同时有用户名和密码环境变量,连接细节走业务账号。随机 root 适合本地不想把 root 口令写进 compose;应用侧只认业务用户。Rabbit 非默认 vhost 则直接写 RABBITMQ_DEFAULT_VHOST,让 ConnectionDetails 带进工厂,不必再手抄一份 spring.rabbitmq.virtual-host 去对齐。
一起交流
分享你的思考,让讨论更进一步。