
Spring 里怎么用设计模式先看变化点再组责任链设计模式解决的是反复出现的变化不是if-else的替代品。只有两三个稳定分支时直接写清判断通常更容易读变化维度独立、规则会持续增加时策略或责任链才值得引入。这篇文章从这条边界出发检查 Spring 项目里常见模式的使用条件、线程安全和失败路径。flowchart TD subgraph SpringAutoAssembly [Spring 容器自动装配 策略责任链组合体系] SpringContext[Spring ApplicationContext] --|1. 自动注入 MapString, PayStrategy| StrategyMap[策略映射容器 (PayStrategyMap)] ClientReq[支付请求 (type: ALIPAY)] -- StrategyMap StrategyMap --|2. O(1) 路由查找| AliPayNode[AliPayStrategy 节点] subgraph ChainExecution [责任链安全执行器 (Chain Engine)] AliPayNode --|3. 节点递进 (Max Depth 10)| RiskNode[风控校验节点] RiskNode --|4. 超时防线 (Timeout 200ms)| LimitNode[限额校验节点] LimitNode --|5. 执行扣款| Execution[第三方 Channel 扣款] end end1. 经典模式的反例与使用边界1.1 策略模式Strategy Pattern❌反例业务逻辑极其固定全系统中仅有“VIP 用户”与“普通用户”两种 9.5 折计算且未来绝不会增加其他类型。有的开发者强行写了DiscountStrategy接口、VipDiscountStrategy类、NormalDiscountStrategy类再搭配一个StrategyFactory类。修改一个折扣参数要打开 5 个文件。✅适用条件与边界业务分支数量大于等于 4 个且属于高度不稳定的频发变更项如支付渠道接入、不同电商节日的营销扣减计算。必须能与 Spring 容器的MapString, Strategy自动注入机制天然结合避免手动写硬编码的Factory类。1.2 责任链模式Chain of Responsibility Pattern❌反例责任链节点未设置深度上限Max Chain Depth与超时控制。当链路节点达到几十个或者发生循环节点引用时直接引发java.lang.StackOverflowError。在并发请求下一个节点的卡死会导致整条责任链持有的线程无法释放。我们在终端中使用jstack诊断责任链过深引发的堆栈溢出或卡死日志jstack 68201 | grep -E at com.example.pattern.chain | head -n 12终端控制台日志输出展示at com.example.pattern.chain.RiskCheckHandler.handle(RiskCheckHandler.java:34) at com.example.pattern.chain.LimitCheckHandler.handle(LimitCheckHandler.java:28) at com.example.pattern.chain.AuthCheckHandler.handle(AuthCheckHandler.java:28) ... (重复 100 次) java.lang.StackOverflowError: Recursion depth exceeded safety threshold针对这个问题责任链模式在生产环境中必须包含递归深度硬限制与单节点 Execution Timeout 保护。2. 生产级Spring 容器装配与安全责任链代码下面是在 Spring Boot 框架下结合MapString, Strategy自动装配与包含深度防线的责任链生产实现代码package com.example.pattern.production; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; // 1. 定义策略接口 public interface PaymentStrategy { String getChannelType(); boolean processPayment(PaymentContext context); } // 2. 策略实现类 1支付宝 Component class AlipayStrategy implements PaymentStrategy { Override public String getChannelType() { return ALIPAY; } Override public boolean processPayment(PaymentContext context) { // 执行支付宝专用扣款逻辑 return true; } } // 3. 策略实现类 2微信支付 Component class WechatPayStrategy implements PaymentStrategy { Override public String getChannelType() { return WECHAT; } Override public boolean processPayment(PaymentContext context) { // 执行微信专用扣款逻辑 return true; } } // 4. 生产级安全策略工厂与责任链调度中枢 Service public class PaymentEngineService { private static final Logger log LoggerFactory.getLogger(PaymentEngineService.class); private static final int MAX_CHAIN_DEPTH 8; // 安全深度上限防护 // Spring 会自动将所有实现 PaymentStrategy 的 Bean 收集并注入到这个 Map 中 private final MapString, PaymentStrategy strategyMap new ConcurrentHashMap(); public PaymentEngineService(ListPaymentStrategy strategies) { for (PaymentStrategy strategy : strategies) { this.strategyMap.put(strategy.getChannelType(), strategy); log.info(已自动装配支付策略节点: [{}] - {}, strategy.getChannelType(), strategy.getClass().getSimpleName()); } } public boolean executePayment(String channelType, PaymentContext context) { PaymentStrategy strategy strategyMap.get(channelType); if (strategy null) { throw new IllegalArgumentException(未找到匹配的支付策略渠道: channelType); } // 校验责任链执行深度防护 if (context.getExecutionDepth() MAX_CHAIN_DEPTH) { log.error( 责任链递归深度 ({} ) 超过安全上限 ({})强行拦截阻断!, context.getExecutionDepth(), MAX_CHAIN_DEPTH); throw new IllegalStateException(责任链执行深度溢出); } context.incrementDepth(); return strategy.processPayment(context); } } // 上下文传递对象 class PaymentContext { private int executionDepth 0; public int getExecutionDepth() { return executionDepth; } public void incrementDepth() { this.executionDepth; } }模式是否值得用取决于变化是否真实存在。引入策略或责任链前先写清新增规则的频率、执行顺序、失败处理和可观测点这些条件不成立时普通分支往往更合适。