Java 设计模式 -- 责任链模式
在日常业务开发中,我们经常遇到串行递进式的处理流程:比如接口鉴权 → 限流校验 → 参数校验 → 业务处理 → 日志记录。
如果把所有逻辑写在一个方法里,代码会臃肿混乱、耦合严重,后期维护极其痛苦。这时候,责任链模式就是最优解。
二、方式一:经典链表式实现(原生标准写法)
2.1 设计思路
这是设计模式原著的标准实现方式:
-
• 每个处理器持有下一个处理器的引用(next),构成单向链表;
-
• 请求从链头进入,处理器自主判断:继续传递/直接终止;
-
• 纯天然责任链,支持任意节点短路终止。
2.2 完整代码实现
① 抽象处理器接口
public interface Handler {
void handle(Request request);
}
② 抽象基类(维护next引用)
public abstract class AbstractHandler implements Handler {
protected AbstractHandler next;
// 设置下一个处理器
public void setNext(AbstractHandler next) {
this.next = next;
}
// 向下传递请求
protected void doNext(Request request) {
if (next != null) {
next.handle(request);
}
}
}
③ 具体业务处理器
// 认证处理器
@Component
public class AuthHandler extends AbstractHandler {
@Override
public void handle(Request request) {
if ("valid-token".equals(request.getToken())) {
System.out.println("[AuthHandler] 认证通过");
doNext(request);
} else {
throw new IllegalArgumentException("认证失败");
}
}
}
// 限流处理器
@Component
public class RateLimitHandler extends AbstractHandler {
@Override
public void handle(Request request) {
System.out.println("[RateLimitHandler] 限流检查通过");
doNext(request);
}
}
// 业务处理器
@Component
public class BusinessHandler extends AbstractHandler {
@Override
public void handle(Request request) {
System.out.println("[BusinessHandler] 开始处理业务: " + request.getData());
}
}
④ 手动组装责任链
@Component
public class HandlerChainClient {
private final AbstractHandler chain;
// 手动编排处理器顺序
public HandlerChainClient(AuthHandler auth, RateLimitHandler rateLimit, BusinessHandler business) {
auth.setNext(rateLimit);
rateLimit.setNext(business);
this.chain = auth;
}
public void execute(Request request) {
chain.handle(request);
}
}
⑤ 实体类 + 测试接口
// 请求实体
@Data
public class Request {
private String token;
private String data;
}
// 测试控制器
@RestController
public class ChainDemoController {
private final HandlerChainClient client;
public ChainDemoController(HandlerChainClient client) {
this.client = client;
}
@GetMapping("/chain/classic")
public String classic() {
Request request = new Request();
request.setToken("valid-token");
request.setData("Hello Chain");
client.execute(request);
return "请求已处理";
}
}
2.3 执行结果
正常请求控制台输出:
[AuthHandler] 认证通过
[RateLimitHandler] 限流检查通过
[BusinessHandler] 开始处理业务: Hello Chain
2.4 优缺点分析
|
✅ 优点 |
❌ 缺点 |
|---|---|
|
贴合原生设计模式,逻辑通俗易懂 |
手动维护next引用,代码冗余 |
|
天然支持流程短路终止 |
新增处理器需修改组装代码,违反开闭原则 |
|
处理器自主控制是否向下传递 |
执行顺序硬编码,调整不灵活 |
三、方式二:Spring List注入式(生产首选推荐)
3.1 设计思路
利用 Spring 核心特性,极简实现责任链,日常开发最优方案:
-
• Spring 自动将同类型 Bean 注入 List 集合;
-
• 通过 @Order 注解 控制执行顺序;
-
• 无需手动组装链表,零耦合扩展。
3.2 完整代码实现
① 定义处理器接口
public interface RequestHandler {
void handle(Request request);
}
② 实现业务处理器(@Order排序)
@Order(1)
@Component
public class AuthHandler implements RequestHandler {
@Override
public void handle(Request request) {
if ("valid-token".equals(request.getToken())) {
System.out.println("[AuthHandler] 认证通过");
} else {
throw new IllegalArgumentException("认证失败");
}
}
}
@Order(2)
@Component
public class RateLimitHandler implements RequestHandler {
@Override
public void handle(Request request) {
System.out.println("[RateLimitHandler] 限流检查通过");
}
}
@Order(3)
@Component
public class BusinessHandler implements RequestHandler {
@Override
public void handle(Request request) {
System.out.println("[BusinessHandler] 处理业务: " + request.getData());
}
}
③ 自动编排责任链(核心)
@Component
public class RequestHandlerChain {
// Spring自动注入所有实现类,按@Order排序
private final List<RequestHandler> handlers;
public RequestHandlerChain(List<RequestHandler> handlers) {
this.handlers = handlers;
}
// 串行执行所有处理器
public void execute(Request request) {
for (RequestHandler handler : handlers) {
handler.handle(request);
}
}
}
④ 调用测试
@RestController
public class ChainDemoController {
private final RequestHandlerChain chain;
public ChainDemoController(RequestHandlerChain chain) {
this.chain = chain;
}
@GetMapping("/chain/injection")
public String injection() {
Request request = new Request();
request.setToken("valid-token");
request.setData("Hello Chain");
chain.execute(request);
return "请求已处理";
}
}
3.3 进阶:优雅实现流程短路
原生写法全部执行,实际业务需要异常终止,自定义上下文实现短路:
① 上下文载体(传递状态、参数)
@Data
public class RequestContext {
private Request request;
private boolean terminated; // 是否终止链路
private String errorMsg;
}
② 改造编排器
public void execute(RequestContext context) {
for (RequestHandler handler : handlers) {
// 终止则直接跳出循环
if (context.isTerminated()) {
break;
}
handler.handle(context);
}
}
3.4 优缺点分析
|
✅ 优点 |
❌ 缺点 |
|---|---|
|
新增处理器直接加类,符合开闭原则 |
默认全部执行,原生不支持短路 |
|
@Order声明式排序,维护简单 |
动态跳过、分支逻辑需要手动扩展 |
|
代码极简、适配Spring生态 |
—— |
四、方式三:函数式流式实现(高阶灵活写法)
4.1 设计思路
基于 Java8+函数式接口(UnaryOperator),将处理器封装为函数,通过流式编程组合链路:
-
• 无需定义过多接口、实现类;
-
• 运行时动态组装链路,灵活性天花板;
-
• 适合管道式、流式处理场景。
4.2 完整代码实现
① 上下文实体
@Data
public class RequestContext {
private final Request request;
private boolean terminated;
private String error;
public RequestContext(Request request) {
this.request = request;
}
}
② 函数式责任链
@Component
public class FunctionalHandlerChain {
private final List<UnaryOperator<RequestContext>> handlers = new ArrayList<>();
// 初始化组装链路
@PostConstruct
public void init() {
handlers.add(this::auth);
handlers.add(this::rateLimit);
handlers.add(this::business);
}
// 执行链路
public RequestContext execute(Request request) {
RequestContext ctx = new RequestContext(request);
for (UnaryOperator<RequestContext> handler : handlers) {
ctx = handler.apply(ctx);
if (ctx.isTerminated()) {
break;
}
}
return ctx;
}
// 认证逻辑
private RequestContext auth(RequestContext ctx) {
if ("valid-token".equals(ctx.getRequest().getToken())) {
System.out.println("[Auth] 通过");
} else {
ctx.setTerminated(true);
ctx.setError("认证失败");
}
return ctx;
}
// 限流逻辑
private RequestContext rateLimit(RequestContext ctx) {
System.out.println("[RateLimit] 通过");
return ctx;
}
// 业务逻辑
private RequestContext business(RequestContext ctx) {
System.out.println("[Business] 处理: " + ctx.getRequest().getData());
return ctx;
}
}
③ 测试接口
@GetMapping("/chain/functional")
public String functional() {
Request request = new Request();
request.setToken("valid-token");
request.setData("Hello Chain");
chain.execute(request);
return "请求已处理";
}
4.3 优缺点分析
|
✅ 优点 |
❌ 缺点 |
|---|---|
|
运行时动态增删、排序链路 |
可读性差,入门门槛高 |
|
流式写法,代码简洁紧凑 |
强依赖函数式编程基础 |
|
天然支持短路、过滤操作 |
调试排查问题难度较大 |
五、三种实现方式横向对比
|
对比维度 |
经典链表式 |
Spring注入式 |
函数式流式 |
|---|---|---|---|
| 扩展性 |
差 |
优秀 |
优秀 |
| 可读性 |
中等 |
优秀 |
较差 |
| Spring耦合 |
低 |
高 |
中等 |
| 短路能力 |
天然支持 |
需自定义上下文 |
原生支持 |
| 适用场景 |
固定链路小型项目 |
绝大多数业务项目 |
动态编排、流式处理 |
六、实战案例:订单处理流水线(生产通用模板)
这里给大家分享一套可直接用于生产的订单责任链模板,采用Spring注入式写法,包含校验、库存、计价、持久化、通知全流程。
6.1 核心实体与接口
// 订单上下文
@Data
public class OrderContext {
private final Order order;
private boolean terminated;
private String errorMsg;
}
// 订单处理器接口
public interface OrderHandler {
void handle(OrderContext ctx);
}
6.2 业务处理器实现
// 1.订单参数校验
@Order(1)
@Component
public class OrderValidationHandler implements OrderHandler {
@Override
public void handle(OrderContext ctx) {
if (ctx.isTerminated()) return;
Order order = ctx.getOrder();
if (order.getAmount() == null || order.getAmount().compareTo(BigDecimal.ZERO) <= 0) {
ctx.setTerminated(true);
ctx.setErrorMsg("订单金额无效");
}
}
}
// 2.库存校验
@Order(2)
@Component
public class InventoryCheckHandler implements OrderHandler {
@Override
public void handle(OrderContext ctx) {
if (ctx.isTerminated()) return;
if (ctx.getOrder().getQuantity() > 100) {
ctx.setTerminated(true);
ctx.setErrorMsg("库存不足");
}
}
}
// 3.金额计算
@Order(3)
@Component
public class PriceCalculateHandler implements OrderHandler {
@Override
public void handle(OrderContext ctx) {
if (ctx.isTerminated()) return;
BigDecimal total = ctx.getOrder().getAmount()
.multiply(BigDecimal.valueOf(ctx.getOrder().getQuantity()));
ctx.getOrder().setTotalAmount(total);
}
}
// 4.订单入库
@Order(4)
@Component
public class OrderPersistHandler implements OrderHandler {
@Override
public void handle(OrderContext ctx) {
if (ctx.isTerminated()) return;
System.out.println("订单已保存: " + ctx.getOrder().getOrderId());
}
}
// 5.消息通知
@Order(5)
@Component
public class OrderNotifyHandler implements OrderHandler {
@Override
public void handle(OrderContext ctx) {
if (ctx.isTerminated()) return;
System.out.println("已发送订单通知给用户: " + ctx.getOrder().getUserId());
}
}
6.3 链路编排 & 接口调用
// 链路编排器
@Component
public class OrderHandlerChain {
private final List<OrderHandler> handlers;
public OrderHandlerChain(List<OrderHandler> handlers) {
this.handlers = handlers;
}
public OrderResult execute(Order order) {
OrderContext ctx = new OrderContext(order);
for (OrderHandler handler : handlers) {
handler.handle(ctx);
if (ctx.isTerminated()) {
return OrderResult.failed(ctx.getErrorMsg());
}
}
return OrderResult.success(order);
}
}
// 控制器
@RestController
@RequestMapping("/orders")
public class OrderController {
private final OrderHandlerChain orderChain;
public OrderController(OrderHandlerChain orderChain) {
this.orderChain = orderChain;
}
@PostMapping
public ResponseEntity<OrderResult> createOrder(@RequestBody Order order) {
OrderResult result = orderChain.execute(order);
return result.isSuccess() ? ResponseEntity.ok(result) : ResponseEntity.badRequest().body(result);
}
}
七、高级实用技巧
7.1 条件装配:按需启用处理器
通过配置文件控制处理器是否生效,无需注释代码:
@Order(6)
@Component
@ConditionalOnProperty(name = "order.vip.enabled", havingValue = "true")
public class VipDiscountHandler implements OrderHandler {
// VIP折扣逻辑
}
7.2 动态跳过:灵活过滤处理器
业务场景差异化,临时跳过指定处理器:
public OrderResult execute(Order order, List<Class<?>> skipHandlers) {
OrderContext ctx = new OrderContext(order);
for (OrderHandler handler : handlers) {
// 跳过指定处理器
if (skipHandlers.contains(handler.getClass())) continue;
if (ctx.isTerminated()) break;
handler.handle(ctx);
}
return ctx.isTerminated() ? OrderResult.failed(ctx.getErrorMsg()) : OrderResult.success(order);
}
7.3 异步处理器:非核心逻辑解耦
日志、消息推送等非核心逻辑,异步执行不阻塞主流程:
@Order(99)
@Component
public class AsyncLogHandler implements OrderHandler {
@Async
@Override
public void handle(OrderContext ctx) {
if (ctx.isTerminated()) return;
// 异步记录审计日志
}
}
八、生产最佳实践总结
-
1. 优先使用Spring注入式:90%的业务场景首选,兼顾可读性、扩展性、维护性;
-
2. 统一上下文载体:所有处理器通过Context传参,禁止自定义参数,统一链路状态;
-
3. 严格遵守单一职责:一个处理器只做一件事,避免臃肿逻辑;
-
4. 规范排序规则:@Order设置步长(10、20、30),避免多人开发序号冲突;
-
5. 拆分核心/非核心逻辑:耗时、非强依赖逻辑异步执行,提升接口响应速度;
-
6. 单独单元测试:每个处理器独立测试,降低排查bug成本。
九、最后总结
责任链模式在Spring Boot中应用极广:拦截器、过滤器、审核流程、订单流水线、参数校验都能见到它的身影。
给大家直白总结三种写法适用场景:
-
• ✅ 经典链表式:简单固定链路、学习理解底层原理;
-
• ✅ Spring注入式:企业开发、生产项目、通用业务编排;
-
• ✅ 函数式流式:动态链路、数据管道、高阶复杂场景。
掌握这三种实现方式,以后遇到串行递进、分层校验的业务,直接套用模板,告别杂乱冗余的if-else!
更多推荐

所有评论(0)