在日常业务开发中,我们经常遇到串行递进式的处理流程:比如接口鉴权 → 限流校验 → 参数校验 → 业务处理 → 日志记录。

如果把所有逻辑写在一个方法里,代码会臃肿混乱、耦合严重,后期维护极其痛苦。这时候,责任链模式就是最优解。
 

二、方式一:经典链表式实现(原生标准写法)

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. 1. 优先使用Spring注入式:90%的业务场景首选,兼顾可读性、扩展性、维护性;

  2. 2. 统一上下文载体:所有处理器通过Context传参,禁止自定义参数,统一链路状态;

  3. 3. 严格遵守单一职责:一个处理器只做一件事,避免臃肿逻辑;

  4. 4. 规范排序规则:@Order设置步长(10、20、30),避免多人开发序号冲突;

  5. 5. 拆分核心/非核心逻辑:耗时、非强依赖逻辑异步执行,提升接口响应速度;

  6. 6. 单独单元测试:每个处理器独立测试,降低排查bug成本。


九、最后总结

责任链模式在Spring Boot中应用极广:拦截器、过滤器、审核流程、订单流水线、参数校验都能见到它的身影。

给大家直白总结三种写法适用场景:

  • • ✅ 经典链表式:简单固定链路、学习理解底层原理;

  • • ✅ Spring注入式:企业开发、生产项目、通用业务编排;

  • • ✅ 函数式流式:动态链路、数据管道、高阶复杂场景。

掌握这三种实现方式,以后遇到串行递进、分层校验的业务,直接套用模板,告别杂乱冗余的if-else!

更多推荐