責任鏈模式將請求的發送者與接收者解耦,多個處理器按順序形成鏈,請求沿鏈傳遞直到某個處理器處理或鏈末端。核心優勢:動態組裝處理邏輯、單一職責、開閉原則。
next 引用public abstract class RequestHandler {
private RequestHandler next;
public RequestHandler setNext(RequestHandler next) {
this.next = next;
return next; // 支持鏈式調用:h1.setNext(h2).setNext(h3)
}
public final void handle(Request request) {
if (canHandle(request)) {
doHandle(request);
} else if (next != null) {
next.handle(request); // 傳遞給下一個
} else {
handleUnprocessed(request); // 鏈末無人處理
}
}
protected abstract boolean canHandle(Request request);
protected abstract void doHandle(Request request);
protected void handleUnprocessed(Request request) {
System.out.println("請求無人處理: " + request);
}
}
public class Request {
private final String type; // 請求類型:AUTH, LOG, RATE_LIMIT, BIZ
private final Map data;
private boolean processed = false;
public Request(String type, Map data) {
this.type = type;
this.data = data;
}
// getter/setter...
}
// 1. 身份認證
public class AuthHandler extends RequestHandler {
@Override protected boolean canHandle(Request req) {
return "AUTH".equals(req.getType());
}
@Override protected void doHandle(Request req) {
String token = (String) req.getData().get("token");
if (TokenValidator.validate(token)) {
req.setProcessed(true);
System.out.println("[Auth] 認證通過");
} else {
throw new AuthException("Token 無效");
}
}
}
// 2. 限流檢查
public class RateLimitHandler extends RequestHandler {
@Override protected boolean canHandle(Request req) {
return "RATE_LIMIT".equals(req.getType());
}
@Override protected void doHandle(Request req) {
String userId = (String) req.getData().get("userId");
if (RateLimiter.tryAcquire(userId)) {
System.out.println("[RateLimit] 通過");
} else {
throw new RateLimitException("請求過於頻繁");
}
}
}
// 3. 業務處理
public class BizHandler extends RequestHandler {
@Override protected boolean canHandle(Request req) {
return "BIZ".equals(req.getType());
}
@Override protected void doHandle(Request req) {
// 具體業務邏輯...
System.out.println("[Biz] 業務處理完成");
req.setProcessed(true);
}
}
// 4. 日誌記錄(全類型處理,不攔截傳遞)
public class LoggingHandler extends RequestHandler {
@Override protected boolean canHandle(Request req) {
return true; // 所有請求都記錄
}
@Override protected void doHandle(Request req) {
System.out.println("[Log] " + req.getType() + " | " + req.getData());
// 不設置 processed,繼續傳遞
}
}
public class ChainClient {
public static void main(String[] args) {
// 構建鏈:日誌 → 認證 → 限流 → 業務
RequestHandler chain = new LoggingHandler();
chain.setNext(new AuthHandler())
.setNext(new RateLimitHandler())
.setNext(new BizHandler());
// 發送請求
Request req = new Request("AUTH", Map.of("token", "valid_token_123"));
chain.handle(req);
// 輸出:
// [Log] AUTH | {token=valid_token_123}
// [Auth] 認證通過
}
}
@Component
@Order(1) // 控制順序
public class SpringAuthHandler extends RequestHandler {
@Autowired TokenService tokenService;
// ... 實現同上
}
@Configuration
public class ChainConfig {
@Bean
public RequestHandler requestChain(List handlers) {
// 按 @Order 排序
handlers.sort(Comparator.comparingInt(h -> h.getClass().getAnnotation(Order.class).value()));
// 串聯
for (int i = 0; i < handlers.size() - 1; i++) {
handlers.get(i).setNext(handlers.get(i + 1));
}
return handlers.get(0);
}
}
// 使用
@RestController
public class ApiController {
@Autowired RequestHandler chain;
@PostMapping("/api")
public Result api(@RequestBody Request req) {
chain.handle(req);
return Result.success();
}
}
| 變體 | 特點 | 適用場景 |
|---|---|---|
| 純傳遞鏈 | 所有節點都執行,不中斷 | 日誌、監控、審計、數據豐富 |
| 攔截鏈 | 某節點處理後終止傳遞 | 認證、限流、緩存命中、熔斷 |
| 動態鏈 | 運行時根據條件增減節點 | 多租戶、功能開關、A/B 測試 |
| 異步鏈 | CompletableFuture 鏈式調用 | 高併發非阻塞處理 |
HandlerExceptionResolver責任鏈模式是構建可擴展、可維護、可測試請求處理管道的利器。Spring 生態中 FilterChain、HandlerInterceptor、GatewayFilterChain 皆是其經典應用。掌握「抽象處理器 + 動態組裝 + 順序控制」三要素,即可靈活應對複雜業務流程編排。