fix(mq-starter): 修复启动 fail-fast 校验 review 发现的缺陷(relaxed binding / 逃生开关 / redis 假地址)

workflow 多智能体 review 后修复:

- rocketmq 探测改用 Binder 读 rocketmq.name-server,与 driver(RocketMQProperties)同源、
  享受 relaxed binding,修复 camelCase(rocketmq.nameServer) 被误判为「未配置」而错误 fail-fast
- MqStartupChecks 逃生开关只认严格 false(忽略大小写/空白),缺省或非法值一律继续校验,
  不再因非法布尔值(如 enabled=disabled)抛类型转换异常炸掉启动
- redis 探测 target() 对 cluster/sentinel 回退到指向真实配置项的文案,
  不再假报使用者从未配过的 localhost:6379
- 补齐回归测试:camelCase 键 / 非法开关值继续校验 / host:port 提示分支 / cluster 回退
  (core 5、redis-stream 5、rocketmq 5,全绿)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-09 14:06:05 +08:00
parent 0c6d37842e
commit 886c02ff96
6 changed files with 91 additions and 5 deletions

View File

@@ -2,7 +2,13 @@ package com.njcn.mq.autoconfig;
import org.springframework.core.env.Environment;
/** MQ 启动校验的公共工具:统一读取逃生开关 {@code mq.startup-check.enabled}(默认 true。 */
/**
* MQ 启动校验的公共工具:统一读取逃生开关 {@code mq.startup-check.enabled}(默认 true
*
* <p>只接受严格的 {@code true}/{@code false}(忽略大小写、去首尾空白)。仅当显式配为
* {@code false} 时才关闭校验;缺省或任何非法值(如 {@code disabled})都按默认 {@code true}
* 继续校验——避免逃生开关自身因非法布尔值在启动期抛类型转换异常,反而把启动炸掉。
*/
public final class MqStartupChecks {
private MqStartupChecks() {
@@ -10,7 +16,7 @@ public final class MqStartupChecks {
/** @return true 表示应执行启动校验false 表示使用者主动关闭。 */
public static boolean enabled(Environment env) {
return Boolean.TRUE.equals(
env.getProperty("mq.startup-check.enabled", Boolean.class, Boolean.TRUE));
String value = env.getProperty("mq.startup-check.enabled");
return value == null || !"false".equalsIgnoreCase(value.trim());
}
}

View File

@@ -34,6 +34,17 @@ class MqDriverPresenceAutoConfigurationTest {
.run(ctx -> assertThat(ctx).hasNotFailed());
}
@Test
void illegalEnabledValue_stillChecks_insteadOfCrashing() {
// 逃生开关填非法布尔值不应炸在类型转换上,而应按默认继续校验:
// 此处无 driver应走到中文③提示而不是 Spring 的「Invalid boolean」类型转换异常。
runner.withPropertyValues("mq.type=redis-stream", "mq.startup-check.enabled=disabled")
.run(ctx -> {
assertThat(ctx).hasFailed();
assertThat(ctx).getFailure().hasMessageContaining("没有装配任何 MqDriver");
});
}
@Test
void disabled_skipsCheck() {
runner.withPropertyValues("mq.type=redis-stream", "mq.startup-check.enabled=false")