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

Spring 經典設計模式深度解析:Template Method 與 Callback 組合藝術

     編輯:Java 相關知識

Spring 核心設計哲學:模板與回調的完美協奏

Spring 框架大量使用模板方法模式與回調模式的組合,這是其消除樣板代碼、提供擴展點、保持框架靈活性的核心架構秘訣。JdbcTemplate、RestTemplate、RedisTemplate、TransactionTemplate 皆是典型代表。

模板方法模式:優勢與困境

經典結構

抽象父類 (Template)
├── templateMethod() final          // 定義算法骨架,不可覆寫
│   ├── step1() protected abstract  // 子類必須實現
│   ├── step2() protected hook      // 子類可選覆寫
│   └── step3() protected abstract  // 子類必須實現
└── 具體子類 1, 2, 3...             // 實現各步驟邏輯

Spring 中的應用:Servlet API

  • HttpServlet 定義 service() 模板方法
  • 按 HTTP 方法分派到 doGet()/doPost() 等鉤子方法
  • 開發者繼承並覆寫所需方法

致命缺陷:繼承耦合與類爆炸

問題影響
單繼承限制 子類無法繼承業務基類,被框架類佔用繼承名額
類爆炸 每個業務變體需新建子類,JdbcTemplate 幾十個方法將導致大量匿名內部類
靜態綁定 編譯期確定行為,運行時難以動態切換策略
受保護方法洩露 protected 方法暴露內部細節,破壞封裝

回調模式:組合優於繼承

核心思想

將可變行為封裝為接口,作為參數傳遞給模板方法,實現運行時行為注入。

Spring 回調接口體系


// JdbcTemplate 核心回調接口
public interface RowMapper {
    T mapRow(ResultSet rs, int rowNum) throws SQLException;
}

public interface ResultSetExtractor {
    T extractData(ResultSet rs) throws SQLException, DataAccessException;
}

public interface PreparedStatementCreator {
    PreparedStatement createPreparedStatement(Connection con) throws SQLException;
}

public interface ConnectionCallback {
    T doInConnection(Connection con) throws SQLException, DataAccessException;
}

組合使用:JdbcTemplate 經典案例

// 模板方法:處理資源獲取、異常轉換、資源釋放等固定流程
public  T query(String sql, RowMapper rowMapper) {
    return execute(new PreparedStatementCreator() {
        public PreparedStatement createPreparedStatement(Connection con) {
            return con.prepareStatement(sql);
        }
    }, new ResultSetExtractor() {
        public T extractData(ResultSet rs) {
            List results = new ArrayList<>();
            int rowNum = 0;
            while (rs.next()) {
                results.add(rowMapper.mapRow(rs, rowNum++)); // 回調:行映射邏輯
            }
            return results;
        }
    });
}

// 使用者代碼:僅關注業務邏輯
List users = jdbcTemplate.query(
    "SELECT id, name, email FROM users WHERE status = ?",
    new Object[]{1},
    (rs, rowNum) -> new User(rs.getLong("id"), rs.getString("name"), rs.getString("email"))
);

何時選擇「模板+回調」vs「純模板方法」

決策矩陣

場景特徵推薦模式理由
每個步驟都有實質性不同邏輯需實現 純模板方法 回調接口過多,反而增加複雜度,不如直接繼承覆寫
僅需定制 1-2 關鍵步驟,其餘固定 模板+回調 接口少、Lambda 簡潔、靈活組合
步驟定制僅涉及參數/配置變化 模板+回調/策略模式 可傳遞配置對象,避免創建大量接口實現
需運行時動態切換行為 模板+回調 組合模式天然支持運行時替換
框架核心流程極其穩定,擴展點固定 模板方法 編譯期約束更強,IDE 支持更好

現代 Spring 演進:函數式風格與 Lambda


// Java 8+ Lambda 极大簡化回調寫法
jdbcTemplate.query(sql, (rs, rowNum) -> new User(...));

// Spring 5+ 函數式 API
Flux users = client.get()
    .uri("/users")
    .retrieve()
    .bodyToFlux(User.class); // 響應式模板

// TransactionTemplate 現代用法
transactionTemplate.execute(status -> {
    // 業務邏輯
    return orderService.createOrder(order);
});

架構層面的深度思考

控制反轉 (IoC) 的體現

  • 模板類控制流程(何時獲取連接、何時提交事務、何時關閉資源)
  • 用戶代碼提供具體行為(SQL 語句、參數綁定、結果映射)
  • 雙方互不依賴具體實現,只依賴抽象接口

與策略模式的關係

  • 回調本質是單方法策略接口
  • 模板方法定義算法骨架,策略/回調填充可變部分
  • Spring 大量使用函數式接口作為輕量級策略

避免過度設計的原則

  1. 固定流程不超過 5-7 步驟,否則考慮責任鏈或管道模式
  2. 回調接口單一職責,避免「上帝接口」
  3. 優先提供默認實現,降低使用門檻
  4. 文檔化執行順序與異常處理語義

總結

Spring 的 Template + Callback 組合是框架設計的教科書級範例:用繼承固定骨架,用組合注入變化。這不僅解決了樣板代碼問題,更通過接口隔離、依賴倒置、單一職責等 SOLID 原則,構建了高內聚、低耦合、易測試、易擴展的企業級框架架構。理解這一模式組合,是掌握 Spring 源碼、設計優雅 API 的關鍵鑰匙。

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