首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 責任鏈模式實戰:請求處理管道靈活組裝

     編輯:Java 相關知識

模式核心思想

責任鏈模式將請求的發送者與接收者解耦,多個處理器按順序形成鏈,請求沿鏈傳遞直到某個處理器處理或鏈末端。核心優勢:動態組裝處理邏輯、單一職責、開閉原則。

經典結構

  • Handler(抽象處理器):定義處理接口,持有 next 引用
  • ConcreteHandler(具體處理器):實現具體邏輯,決定是否傳遞
  • Client(客戶端):構建鏈、發起請求

完整代碼實現

1. 抽象處理器

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);
    }
}

2. 請求對象

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...
}

3. 具體處理器鏈

// 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,繼續傳遞
    }
}

4. 客戶端構建與使用

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] 認證通過
    }
}

Spring 整合:自動裝配鏈

@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 鏈式調用高併發非阻塞處理

避坑指南

  1. 循環引用:構建鏈時檢測環,防止無限遞歸
  2. 請求對象可變性:傳遞過程中多節點修改同一對象,注意線程安全
  3. 異常處理:統一在頂層捕獲,或定義 HandlerExceptionResolver
  4. 性能:鏈過長影響延遲,核心路徑控制在 5-8 節點內
  5. 測試:單元測試每個 Handler,集成測試全鏈路

總結

責任鏈模式是構建可擴展、可維護、可測試請求處理管道的利器。Spring 生態中 FilterChain、HandlerInterceptor、GatewayFilterChain 皆是其經典應用。掌握「抽象處理器 + 動態組裝 + 順序控制」三要素,即可靈活應對複雜業務流程編排。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved