前言
此篇隨筆記錄《How Tomcat works》中關於Lifecycle介面的相關總結
Lifecycle介面的主要目的
核心:統一。
已知Tomcat的卡特琳娜(Catalina)由許多元件構成。當Catalina啟動的時候,這些元件也要跟著一起啟動,並且當Catalina關閉的時候,這些元件也要同時關閉,並且要進行必要的清理操作,釋放資源。例如,當容器關閉的時候,需要呼叫已載入的servlet物件的destroy方法,session物件也要持久化到secondary storage(二級儲存,通常指的就是硬碟)。這就要求所有Component有一致的方法,可以統一處理。
如果沒有統一會怎麼樣?
其實也不會怎麼樣,就是程式設計起來就比較麻煩。比如有的物件初始化方法叫initiate,有的又叫init。用都可以用,就是不太好用,即你要記住這個物件的初始化方法到底叫什麼。而統一之後呢,可以放到一個List中,遍歷呼叫。這不就方便多了嘛。
Lifecycle的事件與監聽
Lifecycle,翻譯過來就是“生命週期”。那生命週期變化,從一個生命週期進入另一個生命週期,自然就會有相應的事件來表示。比如,人從幼兒長大成人,這是一個事件“成長”,而從中年步入老年,又是另外一個事件“衰老”。那麼既然有事件的觸發,那就會有事件的監聽處理,常見的有兩大種。
Lifecycle事件監聽器原理
其實就是觀察者模式了,熟悉的人就不用看了。關聯的類清單如下:
- LifecycleEvent(事件物件)
- Lifecycle 介面
- LifecycleListener 介面
- LifecycleBase => 用於儲存並觸發監聽器,《How Tomcat works》裡是比較舊的,對應的是LifecycleSupport類
(1)LifecycleEvent
LifecycleEvent繼承於EventObject,EventObject是JDK提供的,它只有一個欄位,即Object型別的source,用於表示事件的產生者。
public class EventObject implements java.io.Serializable { private static final long serialVersionUID = 5516075349620653480L; /** * The object on which the Event initially occurred. */ protected transient Object source; public EventObject(Object source) { if (source == null) throw new IllegalArgumentException("null source"); this.source = source; } public Object getSource() { return source; } public String toString() { return getClass().getName() + "[source=" + source + "]"; } }
public final class LifecycleEvent extends EventObject { private static final long serialVersionUID = 1L; /** * * * @param lifecycle 指明當前事件在哪個lifecycle元件上產生 * @param type Event type 事件型別 * @param data Event data 額外的資料 */ public LifecycleEvent(Lifecycle lifecycle, String type, Object data) { //把lifecycle賦給source super(lifecycle); this.type = type; this.data = data; } /** * 與此事件關聯的事件資料 */ private final Object data; /** * 事件型別 */ private final String type; public Object getData() { return data; } public Lifecycle getLifecycle() { return (Lifecycle) getSource(); } public String getType() { return this.type; } }
(2)Lifecycle介面
public interface Lifecycle { //統一的事件型別 public static final String BEFORE_INIT_EVENT = "before_init"; public static final String AFTER_INIT_EVENT = "after_init"; public static final String START_EVENT = "start"; public static final String BEFORE_START_EVENT = "before_start"; public static final String AFTER_START_EVENT = "after_start"; public static final String STOP_EVENT = "stop"; public static final String BEFORE_STOP_EVENT = "before_stop"; public static final String AFTER_STOP_EVENT = "after_stop"; public static final String AFTER_DESTROY_EVENT = "after_destroy"; public static final String BEFORE_DESTROY_EVENT = "before_destroy"; public static final String PERIODIC_EVENT = "periodic"; public static final String CONFIGURE_START_EVENT = "configure_start"; public static final String CONFIGURE_STOP_EVENT = "configure_stop"; //lifecycle表示的是一個元件,故可以在元件上新增監聽器 public void addLifecycleListener(LifecycleListener listener); //獲取註冊在此元件上的監聽器 public LifecycleListener[] findLifecycleListeners(); //移除某個監聽器 public void removeLifecycleListener(LifecycleListener listener); //統一的生命週期方法 public void init() throws LifecycleException; public void start() throws LifecycleException; public void stop() throws LifecycleException; public void destroy() throws LifecycleException; //獲取元件狀態 public LifecycleState getState(); public String getStateName(); public interface SingleUse { } }
(3)LifecycleListener介面
public interface LifecycleListener { //接收事件物件作為引數 //在方法體內,根據事件型別做自定義的響應 public void lifecycleEvent(LifecycleEvent event); }
(4)LifecycleBase 抽象類
一般元件都以此為父類。主要看存監聽器的List和fireLifecycleEvent方法。以下把大部分程式碼省略了,感興趣的可自行翻閱原始碼。
public abstract class LifecycleBase implements Lifecycle { private static final Log log = LogFactory.getLog(LifecycleBase.class); private static final StringManager sm = StringManager.getManager(LifecycleBase.class); //用於儲存註冊在此元件上的監聽器 private final List<LifecycleListener> lifecycleListeners = new CopyOnWriteArrayList<>(); //元件狀態 private volatile LifecycleState state = LifecycleState.NEW; private boolean throwOnFailure = true; public boolean getThrowOnFailure() { return throwOnFailure; } public void setThrowOnFailure(boolean throwOnFailure) { this.throwOnFailure = throwOnFailure; } @Override public void addLifecycleListener(LifecycleListener listener) { lifecycleListeners.add(listener); } @Override public LifecycleListener[] findLifecycleListeners() { return lifecycleListeners.toArray(new LifecycleListener[0]); } @Override public void removeLifecycleListener(LifecycleListener listener) { lifecycleListeners.remove(listener); } //觸發事件,告知所有監聽器。 protected void fireLifecycleEvent(String type, Object data) { LifecycleEvent event = new LifecycleEvent(this, type, data); for (LifecycleListener listener : lifecycleListeners) { listener.lifecycleEvent(event); } } @Override public final synchronized void init() throws LifecycleException { //...省略 } protected abstract void initInternal() throws LifecycleException; @Override public final synchronized void start() throws LifecycleException { //...省略 } protected abstract void startInternal() throws LifecycleException; @Override public final synchronized void stop() throws LifecycleException { //...省略 } protected abstract void stopInternal() throws LifecycleException; @Override public final synchronized void destroy() throws LifecycleException { //...省略 } protected abstract void destroyInternal() throws LifecycleException; @Override public LifecycleState getState() { return state; } @Override public String getStateName() { return getState().toString(); } protected synchronized void setState(LifecycleState state) throws LifecycleException { setStateInternal(state, null, true); } protected synchronized void setState(LifecycleState state, Object data) throws LifecycleException { setStateInternal(state, data, true); } private synchronized void setStateInternal(LifecycleState state, Object data, boolean check) throws LifecycleException { //...省略 } private void invalidTransition(String type) throws LifecycleException { //...省略 } private void handleSubClassException(Throwable t, String key, Object... args) throws LifecycleException { //...省略 } }