企业级脚手架通过“捕获块隐式传播”构建韧性底座:统一异常处理保留原始异常链并标准化错误码,spi 接口强制定义容错契约(iscritical、fallbackresult、@spipriority),结合条件化装配与配置驱动的动态加载沙箱实现故障隔离。
捕获块隐式传播本身不是标准术语,但结合上下文可理解为:在统一异常处理机制中,不显式 throw 新异常,而是保留原始异常链、记录上下文后让其自然向上传递——这种“不拦截、只观测、不掩盖”的异常流处理方式,配合 spi 的解耦扩展能力,恰好构成企业级脚手架的韧性底座。
用 try-catch 包裹校验调用,但不做吞异常或强转
每个 SPI 校验实现(如 InventoryCheck、RiskCheck)都应声明自己的受检/非受检异常类型(如 InsufficientStockException、RiskBlockedException)。主流程用 try-catch 捕获,但仅做三件事:
- 记录关键上下文(请求ID、SKU、用户ID、触发校验名)
- 调用统一错误码映射器,生成标准化错误码(如
ERR_INVENTORY_SHORTAGE) - 原样 re-throw 原始异常,不包装成 RuntimeException,保留栈轨迹和 cause 链
SPI 接口设计需内置容错契约
定义校验 SPI 接口时,强制约定行为边界,而非仅功能签名:
- 添加
boolean isCritical()方法,标识该插件失败是否阻断主流程(如库存校验 critical=true,地址可达性校验 critical=false) - 提供
default fallbackResult()默认兜底返回,供非关键校验降级使用 - 要求实现类声明
@SpiPriority(10)注解,用于排序与熔断策略联动
利用 Spring Boot 的 @Conditional + 异常处理器自动装配容错链
在脚手架的 autoconfigure 模块中,通过条件化装配构建“校验-容错”双层 Bean:
- 用
@ConditionalOnClass(Resilience4jAutoConfiguration.class)控制熔断组件加载 - 为每个 SPI 实现自动生成对应的
Supplier<checkresult></checkresult>装饰器,内嵌超时、重试、降级逻辑 - 全局
@ControllerAdvice统一捕获所有校验异常,根据 error code 渲染不同 HTTP 状态码与响应体,不暴露内部类名
运行时动态启停 + 故障隔离靠 SPI 加载沙箱
不依赖 classpath 扫描,改用独立配置中心驱动 SPI 加载:
- 维护一个
check-plugin-enabled.yml配置,按环境开关插件(如inventory-check: false) - 自定义
ServiceLoader封装类,在加载前校验配置项,跳过禁用插件 - 每个插件在独立 ClassLoader 中初始化,故障时仅卸载对应 loader,不影响其他校验模块










