- 项目使用了 OpenFeign
- Feign 在初始化时,会试图获取 Spring MVC 的相关配置
- 同时,Spring MVC 的自动配置(WebMvcAutoConfiguration)又在等待 Feign 或其他 Bean初始化完成。
- 这会导致死锁/循环依赖,导致 Context 启动失败。
前提是需要使用到上下文,如注入别的Bean,调用服务等
测试环境会尝试加载所有自动配置,包括 Feign 和 WebMvc,而它们在没有完整运行环境(如 Nacos 服务发现)时容易打架。
最终解决办法:
java
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
java
@SpringBootTest(
classes = XxxApplication.class,
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
)
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
这是 Spring Boot 测试中的一个关键配置参数,它的核心含义是:
"请启动一个真实的、嵌入式的 Web 服务器(如 Tomcat),并让它监听一个随机的、未被占用的端口。"
从对比和原理两个角度来看:
| 特性 | 默认模式 (不写参数) | RANDOM_PORT 模式 |
|---|---|---|
| 对应枚举 | WebEnvironment.MOCK |
WebEnvironment.RANDOM_PORT |
| 服务器状态 | ❌ 不启动真实的 Tomcat/Jetty | ✅ 启动真实的嵌入式服务器 |
| 网络请求 | 无法通过 HTTP 访问 (只能用 MockMvc) | 可以通过 http://localhost:随机端口 真实访问 |
| Bean 初始化 | 模拟 Servlet 环境,部分 Web Bean 延迟或特殊初始化 | 完整模拟生产环境,所有 Web Bean 按真实顺序初始化 |
| 端口号 | 无端口 | 随机分配 (如 54321, 61092),避免冲突 |
| 主要用途 | 纯单元测试,速度快 | 集成测试,更接近真实运行环境 |
涉及循环依赖和Feign Client的问题,使用该配置,会要求Spring Boot 先启动真实的 Web 服务器。
服务器启动过程强制要求所有 Web 相关的底层设施(包括 mvcResourceUrlProvider)必须立即、完整地初始化。确保所有 Bean 按正确的生产顺序初始化,从而避开奇怪的循环依赖 Bug。
如果需要在测试代码里知道这个端口是多少,可以注入:
java
@Autowired
private LocalServerConfig serverConfig; // 或者使用 @Value("${local.server.port}")
@Value("${local.server.port}")
private int port;