Java Annotations(註解)自 J2SE 5.0 引入以來,常被視為標記過時代碼的工具。然而,當我們將其視為「可被框架解讀的元資料」而非單純標籤時,它便能成為將方法調用控制權移交給輕量級框架的關鍵機制。本文展示如何利用自定義 Annotations 實現物件初始化流程的外部化管理,實現「做什麼」與「怎麼做」的徹底分離。
企業級應用往往面臨繁瑣的初始化挑戰:建立面板、配置服務、資料載入……部分步驟需重複執行,部分則否。若由類別自行管理邏輯,不僅違反單一職責原則,更會因流程變更導致維護惡夢。現代軟體設計強調關注點分離——我們需要一種機制,讓類別專注業務邏輯,而流程編排交給外部框架。
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Phase {
int index(); // 執行順序索引(必填)
String displayName() default ""; // 顯示名稱,可用於進度條監控
}
@Retention(RUNTIME):確保註解保留至執行期,供反射讀取@Target(METHOD):限定僅能標註方法index():定義階段在操作鏈中的順序public interface Phased {} // 所有可被框架管理的介面需繼承此標記
public interface PhasedMask extends Phased {
@Phase(index = 0) void construct(); // 建構:僅執行一次
@Phase(index = 1) void initialize(); // 初始化:載入資料填充欄位
@Phase(index = 2, displayName = "Activating...") void activate(); // 啟動:釋放控制權
}
public class MyMask implements PhasedMask {
@Phase(index = 0)
public void construct() { /* 版面配置 */ }
@Phase(index = 1)
public void initialize() { /* 從 DB/檔案載入資料 */ }
@Phase(index = 2)
public void activate() { /* 啟用監聽器,允許用戶互動 */ }
// 業務代碼...
}
Phaser 類別負責掃描註解、按序調用方法、提供監控擴充點:
// 基本調用:按索引順序執行所有階段
Phaser phaser = new Phaser(phasedMask);
phaser.invokeAll(); // 依序呼叫 construct → initialize → activate
// 進階控制:跳過階段、重排順序、指定階段名
phaser.invoke(new int[]{1, 2}); // 跳過 construct (index 0)
phaser.invoke(new String[]{"initialize", "activate"}); // 使用方法名更直觀
phaser.invoke(new String[]{"activate", "initialize"}); // 甚至可重排順序(特定場景有用)
PhaseListener listener = new PhaseListener() {
public void before(PhaseEvent e) { /* 階段開始前:更新 UI 進度條 */ }
public void after(PhaseEvent e) { /* 階段結束後:記錄日誌、效能統計 */ }
};
phaser.addPhaseListener(listener);
phaser.invoke(new String[]{"initialize", "activate"});
本文展示的模式證明:Annotations 不僅是文檔工具,更是行為控制的宣告式指令。將生命週期管理外部化至 Phaser 等框架組件,讓類別回歸純粹的業務載體,這正是輕量級容器(如 Spring)興起的核心哲學縮影。在適用場景下,這種「配置勝過編碼」的思維能顯著降低系統複雜度。