在複雜的 Java 應用系統中,組件(如資料庫連接池、網路服務、執行緒池、快取模組)的啟動、運行與銷毀往往伴隨著資源的分配與釋放。若缺乏統一的管理機制,容易導致資源洩漏、狀態不一致或關閉順序錯誤等問題。一套健壯的生命週期管理框架,能將這些雜亂的資源控制邏輯標準化、集中化,提升系統的可維護性與穩定性。
首先定義一個頂層介面 ILifecycle,規範組件的基本狀態流轉:
public interface ILifecycle {
void init() throws LifecycleException;
void start() throws LifecycleException;
void suspend() throws LifecycleException;
void resume() throws LifecycleException;
void destroy() throws LifecycleException;
LifecycleState getState();
void addLifecycleListener(ILifecycleListener listener);
void removeLifecycleListener(ILifecycleListener listener);
}
狀態枚舉 LifecycleState 包含 NEW、INITIALIZED、STARTED、SUSPENDED、DESTROYED 等,確保狀態轉換的合法性(例如必須先 init 才能 start)。
抽象類 AbstractLifecycle 封裝了通用邏輯:狀態校驗、監聽器觸發、線程安全的狀態設置,並留出受保護的模板方法供子類實現具體業務:
public abstract class AbstractLifecycle implements ILifecycle {
private LifecycleState state = LifecycleState.NEW;
private final List listeners = new CopyOnWriteArrayList<>();
// 公開方法委託給受保護的模板方法,並處理狀態流轉與事件通知
@Override
public final synchronized void init() throws LifecycleException {
if (state != LifecycleState.NEW) throw new IllegalStateException("...");
setStateAndFireEvent(LifecycleState.INITIALIZING);
try { init0(); } catch (Exception e) { ... }
setStateAndFireEvent(LifecycleState.INITIALIZED);
}
// start(), suspend(), resume(), destroy() 同理...
// 子類必須實現的具體邏輯
protected abstract void init0() throws LifecycleException;
protected abstract void start0() throws LifecycleException;
protected abstract void suspend0() throws LifecycleException;
protected abstract void resume0() throws LifecycleException;
protected abstract void destroy0() throws LifecycleException;
// 監聽器管理、狀態設置與事件觸發輔助方法...
}
這裡採用了模板方法模式,將固定的流程(狀態檢查、事件發布)固化在父類,將變化的業務邏輯延遲到子類。
為了讓實現類只關心自己需要的階段,提供一個適配器類 DefaultLifecycle,所有模板方法預設為空操作:
public class DefaultLifecycle extends AbstractLifecycle {
@Override protected void init0() {}
@Override protected void start0() {}
@Override protected void suspend0() {}
@Override protected void resume0() {}
@Override protected void destroy0() {}
}
實際業務類只需繼承 DefaultLifecycle 並覆寫感興趣的方法,避免了強制實現所有介面方法的負擔。
以下展示一個基於此框架的 TCP 伺服器,清晰地在各生命週期階段管理 Socket 資源:
public class SocketServer extends DefaultLifecycle {
private ServerSocket acceptor;
private final int port = 9527;
@Override
protected void init0() throws LifecycleException {
try { acceptor = new ServerSocket(port); }
catch (IOException e) { throw new LifecycleException("端口綁定失敗", e); }
}
@Override
protected void start0() throws LifecycleException {
// 實際生產中通常另啟執行緒循環 accept,此處簡化示範單次接受
try (Socket socket = acceptor.accept()) {
// 處理業務邏輯...
} catch (IOException e) { throw new LifecycleException("接受連接異常", e); }
}
@Override
protected void destroy0() throws LifecycleException {
if (acceptor != null) {
try { acceptor.close(); }
catch (IOException e) { /* 記錄日誌 */ }
}
}
}
使用時只需:
ILifecycle server = new SocketServer();
server.init();
server.start();
// ... 運行一段時間 ...
server.destroy(); // 確保資源釋放
透過 ILifecycleListener 可實現如「關閉前刷新快取」、「啟動後註冊服務發現」等橫切關注點:
server.addLifecycleListener(event -> {
if (event.getState() == LifecycleState.STARTED) {
serviceRegistry.register("socket-server", port);
} else if (event.getState() == LifecycleState.DESTROYED) {
serviceRegistry.deregister("socket-server");
}
});
這套機制的優勢在於:
無論是微服務中的組件管理、中間件開發,還是日常業務模組的資源控制,這種模式都能帶來結構清晰、易於測試與維護的代碼結構。