責任鏈模式是行為型設計模式的經典代表,通過將請求處理者串聯成鏈,實現請求發送者與接收者的解耦。本文系統講解其核心角色、UML 結構、Java 完整實現、Web 過濾器/攔截器中的實戰應用、優缺點權衡及擴展變體。
核心思想:將請求處理細節(由誰處理、怎麼處理、按什麼順序)從客戶端代碼中剝離,封裝在鏈式結構中。客戶端只需將請求發送給鏈頭,無需關心後續流轉邏輯。
HandlerExceptionResolver 鏈。
| 角色 | 職責 | 關鍵方法 |
|---|---|---|
| Handler (抽象處理者) | 定義處理請求的接口,可選持有後繼者引用 | handleRequest(Request), setNext(Handler) |
| ConcreteHandler (具體處理者) | 處理自己能處理的請求,否則傳遞給後繼者 | 重寫 handleRequest |
| Client (客戶端) | 組裝鏈結構,發起請求 | 調用 headHandler.handleRequest(req) |
public abstract class Handler {
protected Handler successor;
public abstract void handleRequest(String condition);
public Handler getSuccessor() { return successor; }
public void setSuccessor(Handler successor) { this.successor = successor; }
// 模板方法:處理完畢自動傳遞
protected void passToNext(String condition) {
if (successor != null) {
successor.handleRequest(condition);
}
}
}
public class ConcreteHandler1 extends Handler {
@Override
public void handleRequest(String condition) {
System.out.println("ConcreteHandler1 處理請求: " + condition);
// 業務邏輯...
passToNext(condition); // 傳遞給下一個
}
}
public class ConcreteHandler2 extends Handler {
@Override
public void handleRequest(String condition) {
System.out.println("ConcreteHandler2 處理請求: " + condition);
passToNext(condition);
}
}
public class ConcreteHandler3 extends Handler {
@Override
public void handleRequest(String condition) {
System.out.println("ConcreteHandler3 處理請求: " + condition);
// 最後一個可選擇不傳遞,或傳遞給終結節點
passToNext(condition);
}
}
public class Client {
public static void main(String[] args) {
Handler h1 = new ConcreteHandler1();
Handler h2 = new ConcreteHandler2();
Handler h3 = new ConcreteHandler3();
// 建立鏈:h1 → h2 → h3
h1.setSuccessor(h2);
h2.setSuccessor(h3);
// 發起請求
h1.handleRequest("訂單創建請求");
}
}
| 變體 | 特點 | 適用場景 |
|---|---|---|
| 純責任鏈 | 每個處理者要么全權處理,要么完全傳遞,不允許部分處理後傳遞 | |
| 不純責任鏈 | 處理者可部分處理後傳遞,或處理完仍傳遞(如 Servlet Filter chain.doFilter() 前後邏輯) |
|
| 動態鏈構建 | 運行時根據配置/註解動態組裝順序(Spring @Order、Dubbo @Activate) |
// ApplicationFilterChain 核心邏輯 (Tomcat 簡化版)
public final class ApplicationFilterChain implements FilterChain {
private final List filters = new ArrayList<>();
private int position = 0;
@Override
public void doFilter(ServletRequest request, ServletResponse response) {
if (position < filters.size()) {
Filter filter = filters.get(position++);
filter.doFilter(request, response, this); // 關鍵:傳遞 this (鏈對象)
} else {
// 終點:調用 Servlet.service()
servlet.service(request, response);
}
}
public void addFilter(Filter filter) { filters.add(filter); }
}
關鍵設計:FilterChain 作為鏈對象傳遞,filter.doFilter(req, res, chain) 由開發者決定是否調用 chain.doFilter() 及調用前後邏輯,極其靈活。
if-else if-else 鏈。@Order、優先級字段、拓撲排序,保證鏈順序確定性。Mono/Flux 鏈、CompletableFuture 鏈,避免阻塞線程。責任鏈模式以「鏈式委託」替代「集中控制」,是構建可擴展、低耦合處理管道的利器。從 Servlet Filter 到 Spring Interceptor,從 Netty Pipeline 到 Dubbo Filter,它是 Java 生態中中間件、框架、業務流程引擎的基石架構。掌握其純/不純變體、動態組裝、調試觀測、性能調優,是高級 Java 開發者的必備架構能力。