Tomcat裡面有各種各樣的元件,每個元件各司其職,元件之間又相互協作共同完成web伺服器這樣的工程。在這些元件之上,Lifecycle(生命週期機制)至關重要!在學習各個元件之前,我們需要看看Lifecycle是什麼以及能做什麼?實現原理又是怎樣的?
什麼是Lifecycle?
Lifecycle,其實就是一個狀態機,對元件的由生到死狀態的管理。
- 當元件在
STARTING_PREP
、STARTING
或STARTED
時,呼叫start()
方法沒有任何效果 - 當元件在
NEW
狀態時,呼叫start()
方法會導致init()
方法被立刻執行,隨後start()
方法被執行 - 當元件在
STOPPING_PREP
、STOPPING
或STOPPED
時,呼叫stop()
方法沒有任何效果 - 當一個元件在
NEW
狀態時,呼叫stop()
方法會將元件狀態變更為STOPPED
,比較典型的場景就是元件啟動失敗,其子元件還沒有啟動。當一個元件停止的時候,它將嘗試停止它下面的所有子元件,即使子元件還沒有啟動。
Lifecycle方法
我們看看Lifecycle有哪些方法,如下所示:
public interface Lifecycle { // 新增監聽器 public void addLifecycleListener(LifecycleListener listener); // 獲取所以監聽器 public LifecycleListener[] findLifecycleListeners(); // 移除某個監聽器 public void removeLifecycleListener(LifecycleListener listener); // 初始化方法 public void init() throws LifecycleException; // 啟動方法 public void start() throws LifecycleException; // 停止方法,和start對應 public void stop() throws LifecycleException; // 銷燬方法,和init對應 public void destroy() throws LifecycleException; // 獲取生命週期狀態 public LifecycleState getState(); // 獲取字串型別的生命週期狀態 public String getStateName(); }
LifecycleBase
LifecycleBase
是Lifecycle
的基本實現。我們逐一來看Lifecycle的各個方法。
增加、刪除和獲取監聽器
private final List<LifecycleListener> lifecycleListeners = new CopyOnWriteArrayList<>(); @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); }
- 生命週期監聽器儲存在一個執行緒安全的List中,
CopyOnWriteArrayList
。所以add和remove都是直接呼叫此List的相應方法。 - findLifecycleListeners返回的是一個陣列,為了執行緒安全,所以這兒會生成一個新陣列。
init()
@Override public final synchronized void init() throws LifecycleException { // 非NEW狀態,不允許呼叫init()方法 if (!state.equals(LifecycleState.NEW)) { invalidTransition(Lifecycle.BEFORE_INIT_EVENT); } try { // 初始化邏輯之前,先將狀態變更為`INITIALIZING` setStateInternal(LifecycleState.INITIALIZING, null, false); // 初始化,該方法為一個abstract方法,需要元件自行實現 initInternal(); // 初始化完成之後,狀態變更為`INITIALIZED` setStateInternal(LifecycleState.INITIALIZED, null, false); } catch (Throwable t) { // 初始化的過程中,可能會有異常丟擲,這時需要捕獲異常,並將狀態變更為`FAILED` ExceptionUtils.handleThrowable(t); setStateInternal(LifecycleState.FAILED, null, false); throw new LifecycleException( sm.getString("lifecycleBase.initFail",toString()), t); } }
setStateInternal
方法用於維護狀態,同時在狀態轉換成功之後觸發事件。為了狀態的可見性,所以state宣告為volatile型別的。
private volatile LifecycleState state = LifecycleState.NEW;。
private synchronized void setStateInternal(LifecycleState state, Object data, boolean check) throws LifecycleException { if (log.isDebugEnabled()) { log.debug(sm.getString("lifecycleBase.setState", this, state)); } // 是否校驗狀態 if (check) { // Must have been triggered by one of the abstract methods (assume // code in this class is correct) // null is never a valid state // state不允許為null if (state == null) { invalidTransition("null"); // Unreachable code - here to stop eclipse complaining about // a possible NPE further down the method return; } // Any method can transition to failed // startInternal() permits STARTING_PREP to STARTING // stopInternal() permits STOPPING_PREP to STOPPING and FAILED to // STOPPING if (!(state == LifecycleState.FAILED || (this.state == LifecycleState.STARTING_PREP && state == LifecycleState.STARTING) || (this.state == LifecycleState.STOPPING_PREP && state == LifecycleState.STOPPING) || (this.state == LifecycleState.FAILED && state == LifecycleState.STOPPING))) { // No other transition permitted invalidTransition(state.name()); } } // 設定狀態 this.state = state; // 觸發事件 String lifecycleEvent = state.getLifecycleEvent(); if (lifecycleEvent != null) { fireLifecycleEvent(lifecycleEvent, data); } }
我們看看fireLifecycleEvent
方法,
public void fireLifecycleEvent(String type, Object data) { // 事件監聽,觀察者模式的另一種方式 LifecycleEvent event = new LifecycleEvent(lifecycle, type, data); LifecycleListener interested[] = listeners;// 監聽器陣列 關注 事件(啟動或者關閉事件) // 迴圈通知所有生命週期時間偵聽器 for (int i = 0; i < interested.length; i++) // 每個監聽器都有自己的邏輯 interested[i].lifecycleEvent(event); }
首先, 建立一個事件物件, 然通知所有的監聽器發生了該事件.並做響應.
start()
@Override public final synchronized void start() throws LifecycleException { // `STARTING_PREP`、`STARTING`和`STARTED時,將忽略start()邏輯 if (LifecycleState.STARTING_PREP.equals(state) || LifecycleState.STARTING.equals(state) || LifecycleState.STARTED.equals(state)) { if (log.isDebugEnabled()) { Exception e = new LifecycleException(); log.debug(sm.getString("lifecycleBase.alreadyStarted", toString()), e); } else if (log.isInfoEnabled()) { log.info(sm.getString("lifecycleBase.alreadyStarted", toString())); } return; } // `NEW`狀態時,執行init()方法 if (state.equals(LifecycleState.NEW)) { init(); } // `FAILED`狀態時,執行stop()方法 else if (state.equals(LifecycleState.FAILED)) { stop(); } // 不是`INITIALIZED`和`STOPPED`時,則說明是非法的操作 else if (!state.equals(LifecycleState.INITIALIZED) && !state.equals(LifecycleState.STOPPED)) { invalidTransition(Lifecycle.BEFORE_START_EVENT); } try { // start前的狀態設定 setStateInternal(LifecycleState.STARTING_PREP, null, false); // start邏輯,抽象方法,由元件自行實現 startInternal(); // start過程中,可能因為某些原因失敗,這時需要stop操作 if (state.equals(LifecycleState.FAILED)) { // This is a 'controlled' failure. The component put itself into the // FAILED state so call stop() to complete the clean-up. stop(); } else if (!state.equals(LifecycleState.STARTING)) { // Shouldn't be necessary but acts as a check that sub-classes are // doing what they are supposed to. invalidTransition(Lifecycle.AFTER_START_EVENT); } else { // 設定狀態為STARTED setStateInternal(LifecycleState.STARTED, null, false); } } catch (Throwable t) { // This is an 'uncontrolled' failure so put the component into the // FAILED state and throw an exception. ExceptionUtils.handleThrowable(t); setStateInternal(LifecycleState.FAILED, null, false); throw new LifecycleException(sm.getString("lifecycleBase.startFail", toString()), t); } }
stop()
@Override public final synchronized void stop() throws LifecycleException { // `STOPPING_PREP`、`STOPPING`和STOPPED時,將忽略stop()的執行 if (LifecycleState.STOPPING_PREP.equals(state) || LifecycleState.STOPPING.equals(state) || LifecycleState.STOPPED.equals(state)) { if (log.isDebugEnabled()) { Exception e = new LifecycleException(); log.debug(sm.getString("lifecycleBase.alreadyStopped", toString()), e); } else if (log.isInfoEnabled()) { log.info(sm.getString("lifecycleBase.alreadyStopped", toString())); } return; } // `NEW`狀態時,直接將狀態變更為`STOPPED` if (state.equals(LifecycleState.NEW)) { state = LifecycleState.STOPPED; return; } // stop()的執行,必須要是`STARTED`和`FAILED` if (!state.equals(LifecycleState.STARTED) && !state.equals(LifecycleState.FAILED)) { invalidTransition(Lifecycle.BEFORE_STOP_EVENT); } try { // `FAILED`時,直接觸發BEFORE_STOP_EVENT事件 if (state.equals(LifecycleState.FAILED)) { // Don't transition to STOPPING_PREP as that would briefly mark the // component as available but do ensure the BEFORE_STOP_EVENT is // fired fireLifecycleEvent(BEFORE_STOP_EVENT, null); } else { // 設定狀態為STOPPING_PREP setStateInternal(LifecycleState.STOPPING_PREP, null, false); } // stop邏輯,抽象方法,元件自行實現 stopInternal(); // Shouldn't be necessary but acts as a check that sub-classes are // doing what they are supposed to. if (!state.equals(LifecycleState.STOPPING) && !state.equals(LifecycleState.FAILED)) { invalidTransition(Lifecycle.AFTER_STOP_EVENT); } // 設定狀態為STOPPED setStateInternal(LifecycleState.STOPPED, null, false); } catch (Throwable t) { ExceptionUtils.handleThrowable(t); setStateInternal(LifecycleState.FAILED, null, false); throw new LifecycleException(sm.getString("lifecycleBase.stopFail",toString()), t); } finally { if (this instanceof Lifecycle.SingleUse) { // Complete stop process first setStateInternal(LifecycleState.STOPPED, null, false); destroy(); } } }
destroy()
@Override public final synchronized void destroy() throws LifecycleException { // `FAILED`狀態時,直接觸發stop()邏輯 if (LifecycleState.FAILED.equals(state)) { try { // Triggers clean-up stop(); } catch (LifecycleException e) { // Just log. Still want to destroy. log.warn(sm.getString( "lifecycleBase.destroyStopFail", toString()), e); } } // `DESTROYING`和`DESTROYED`時,忽略destroy的執行 if (LifecycleState.DESTROYING.equals(state) || LifecycleState.DESTROYED.equals(state)) { if (log.isDebugEnabled()) { Exception e = new LifecycleException(); log.debug(sm.getString("lifecycleBase.alreadyDestroyed", toString()), e); } else if (log.isInfoEnabled() && !(this instanceof Lifecycle.SingleUse)) { // Rather than have every component that might need to call // destroy() check for SingleUse, don't log an info message if // multiple calls are made to destroy() log.info(sm.getString("lifecycleBase.alreadyDestroyed", toString())); } return; } // 非法狀態判斷 if (!state.equals(LifecycleState.STOPPED) && !state.equals(LifecycleState.FAILED) && !state.equals(LifecycleState.NEW) && !state.equals(LifecycleState.INITIALIZED)) { invalidTransition(Lifecycle.BEFORE_DESTROY_EVENT); } try { // destroy前狀態設定 setStateInternal(LifecycleState.DESTROYING, null, false); // 抽象方法,元件自行實現 destroyInternal(); // destroy後狀態設定 setStateInternal(LifecycleState.DESTROYED, null, false); } catch (Throwable t) { ExceptionUtils.handleThrowable(t); setStateInternal(LifecycleState.FAILED, null, false); throw new LifecycleException( sm.getString("lifecycleBase.destroyFail",toString()), t); } }
模板方法
從上述原始碼看得出來,LifecycleBase
是使用了狀態機+模板模式來實現的。模板方法有下面這幾個:
// 初始化方法 protected abstract void initInternal() throws LifecycleException; // 啟動方法 protected abstract void startInternal() throws LifecycleException; // 停止方法 protected abstract void stopInternal() throws LifecycleException; // 銷燬方法 protected abstract void destroyInternal() throws LifecycleException;
總結
Lifecycle其實非常簡單,程式碼也不復雜,但是剖析其實現對於我們理解元件的生命週期有很大的幫助,也有助於我們對設計模式的回顧。