【雜談】Tomcat 之 Lifecycle介面

貓毛·波拿巴發表於2019-04-01

前言

  此篇隨筆記錄《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 {
        //...省略
    }
}

 

相關文章