成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Java實現(xiàn)生命周期管理機制

LiuRhoRamen / 2991人閱讀

摘要:可以這么實現(xiàn)代表當前生命周期狀態(tài)可以看到,抽象類的骨架實現(xiàn)中做了幾件生命周期管理中通用的事情,檢查狀態(tài)之間的轉(zhuǎn)換是否合法比如說之前必須要,設(shè)置內(nèi)部狀態(tài),以及觸發(fā)相應(yīng)的監(jiān)聽者。

先扯再說

最近一直在研究某個國產(chǎn)開源的MySQL數(shù)據(jù)庫中間件,拉下其最新版的代碼到eclipse后,啟動起來,然后做各種測試和代碼追蹤;用完想要關(guān)閉它時,拉出它的STOP類想要運行時,發(fā)現(xiàn)這個類里赫然只寫以下幾行代碼,于是我感覺瞬間受到了很多傷害。

    public static void main(String[] args) {
        System.out.println(new Date() + ",server shutdown!");
    }

這個中間件啟動和運行的時候,開啟了監(jiān)聽,啟動著許多線程在跑著,并且有許多socket連接。但是并沒有找到一個優(yōu)雅的方式將其關(guān)閉。于是無奈之下,我只能去點eclipse的心碎小紅點,強行停掉VM。

如果是一個架構(gòu)良好,模塊化清晰的軟件,特別是Server類的軟件,擁有一套生命周期管理機制是非常重要的。不僅可以管理各個模塊的生命周期,也可以在啟停整個軟件的時候更優(yōu)雅,不會漏掉任何資源。

生命周期機制簡易實現(xiàn) 生命周期狀態(tài)

一個模塊的生命周期狀態(tài)一般有以下幾個:

新生 -> 初始化中 -> 初始化完成 -> 啟動中 -> 啟動完成 -> 正在暫停 -> 已經(jīng)暫停 -> 正在恢復(fù) -> 已經(jīng)恢復(fù) -> 正在銷毀 -> 已經(jīng)銷毀

其中,任何一個狀態(tài)之間的轉(zhuǎn)化如果失敗,那么就會進入另外一種狀態(tài):失敗。

為此,可以用一個枚舉類來枚舉出這幾個狀態(tài),如下所示:

public enum LifecycleState {

    NEW, //新生

    INITIALIZING, INITIALIZED, //初始化

    STARTING, STARTED, //啟動

    SUSPENDING, SUSPENDED, //暫停

    RESUMING, RESUMED,//恢復(fù)

    DESTROYING, DESTROYED,//銷毀

    FAILED;//失敗

}
接口

生命周期中的各種行為規(guī)范,也需要一個接口來定義,如下所示:

public interface ILifecycle {

    /**
     * 初始化
     * 
     * @throws LifecycleException
     */
    public void init() throws LifecycleException;

    /**
     * 啟動
     * 
     * @throws LifecycleException
     */
    public void start() throws LifecycleException;

    /**
     * 暫停
     * 
     * @throws LifecycleException
     */
    public void suspend() throws LifecycleException;

    /**
     * 恢復(fù)
     * 
     * @throws LifecycleException
     */
    public void resume() throws LifecycleException;

    /**
     * 銷毀
     * 
     * @throws LifecycleException
     */
    public void destroy() throws LifecycleException;

    /**
     * 添加生命周期監(jiān)聽器
     * 
     * @param listener
     */
    public void addLifecycleListener(ILifecycleListener listener);

    /**
     * 刪除生命周期監(jiān)聽器
     * 
     * @param listener
     */
    public void removeLifecycleListener(ILifecycleListener listener);

}

發(fā)生生命周期狀態(tài)轉(zhuǎn)化時,可能需要觸發(fā)對某類事件感興趣的監(jiān)聽者,因此ILifeCycle也定義了兩個方法可以添加和移除監(jiān)聽者。分別是:public void addLifecycleListener(ILifecycleListener listener); public void removeLifecycleListener(ILifecycleListener listener);

監(jiān)聽者也由一個接口來定義其行為規(guī)范,如下所示:

public interface ILifecycleListener {

    /**
     * 對生命周期事件進行處理
     * 
     * @param event 生命周期事件
     */
    public void lifecycleEvent(LifecycleEvent event);
}

生命周期事件由LifecycleEvent來表示,如下所示:

public final class LifecycleEvent {

    private LifecycleState state;

    public LifecycleEvent(LifecycleState state) {
        this.state = state;
    }

    /**
     * @return the state
     */
    public LifecycleState getState() {
        return state;
    }

}
骨架實現(xiàn)

有了ILifeCycle接口以后,任何實現(xiàn)了這個接口的類將會被作為一個生命周期管理對象,這個類可以是一個socket監(jiān)聽服務(wù),也可以代表一個特定的模塊,等等。那我們是不是只要實現(xiàn)ILifeCycle就可以了? 可以這么說,但考慮到各個生命周期管理對象在生命周期的各個階段會有一些共同的行為,比如說:

設(shè)置自身的生命周期狀態(tài)

檢查狀態(tài)的轉(zhuǎn)換是否符合邏輯

通知監(jiān)聽者生命周期狀態(tài)發(fā)生了變化

因此,提供一個抽象類AbstractLifeCycle,作為ILifeCycle骨架實現(xiàn)是有重要意義的,這樣避免了很多的重復(fù)代碼,使得架構(gòu)更加清晰。這個抽象類會實現(xiàn)ILifeCycle中定義的所有接口方法,并添加對應(yīng)的抽象方法,供子類實現(xiàn)。AbstractLifeCycle可以這么實現(xiàn):

public abstract class AbstractLifecycle implements ILifecycle {

    private List listeners = new CopyOnWriteArrayList();

    /**
     * state 代表當前生命周期狀態(tài)
     */
    private LifecycleState state = LifecycleState.NEW;

    /*
     * @see ILifecycle#init()
     */
    @Override
    public final synchronized void init() throws LifecycleException {
        if (state != LifecycleState.NEW) {
            return;
        }

        setStateAndFireEvent(LifecycleState.INITIALIZING);
        try {
            init0();
        } catch (Throwable t) {
            setStateAndFireEvent(LifecycleState.FAILED);
            if (t instanceof LifecycleException) {
                throw (LifecycleException) t;
            } else {
                throw new LifecycleException(formatString(
                        "Failed to initialize {0}, Error Msg: {1}", toString(), t.getMessage()), t);
            }
        }
        setStateAndFireEvent(LifecycleState.INITIALIZED);
    }

    protected abstract void init0() throws LifecycleException;

    /*
     * @see ILifecycle#start()
     */
    @Override
    public final synchronized void start() throws LifecycleException {
        if (state == LifecycleState.NEW) {
            init();
        }

        if (state != LifecycleState.INITIALIZED) {
            return;
        }

        setStateAndFireEvent(LifecycleState.STARTING);
        try {
            start0();
        } catch (Throwable t) {
            setStateAndFireEvent(LifecycleState.FAILED);
            if (t instanceof LifecycleException) {
                throw (LifecycleException) t;
            } else {
                throw new LifecycleException(formatString("Failed to start {0}, Error Msg: {1}",
                        toString(), t.getMessage()), t);
            }
        }
        setStateAndFireEvent(LifecycleState.STARTED);
    }

    protected abstract void start0() throws LifecycleException;

    /*
     * @see ILifecycle#suspend()
     */
    @Override
    public final synchronized void suspend() throws LifecycleException {
        if (state == LifecycleState.SUSPENDING || state == LifecycleState.SUSPENDED) {
            return;
        }

        if (state != LifecycleState.STARTED) {
            return;
        }

        setStateAndFireEvent(LifecycleState.SUSPENDING);
        try {
            suspend0();
        } catch (Throwable t) {
            setStateAndFireEvent(LifecycleState.FAILED);
            if (t instanceof LifecycleException) {
                throw (LifecycleException) t;
            } else {
                throw new LifecycleException(formatString("Failed to suspend {0}, Error Msg: {1}",
                        toString(), t.getMessage()), t);
            }
        }
        setStateAndFireEvent(LifecycleState.SUSPENDED);
    }

    protected abstract void suspend0() throws LifecycleException;

    /*
     * @see ILifecycle#resume()
     */
    @Override
    public final synchronized void resume() throws LifecycleException {
        if (state != LifecycleState.SUSPENDED) {
            return;
        }

        setStateAndFireEvent(LifecycleState.RESUMING);
        try {
            resume0();
        } catch (Throwable t) {
            setStateAndFireEvent(LifecycleState.FAILED);
            if (t instanceof LifecycleException) {
                throw (LifecycleException) t;
            } else {
                throw new LifecycleException(formatString("Failed to resume {0}, Error Msg: {1}",
                        toString(), t.getMessage()), t);
            }
        }
        setStateAndFireEvent(LifecycleState.RESUMED);
    }

    protected abstract void resume0() throws LifecycleException;

    /*
     * @see ILifecycle#destroy()
     */
    @Override
    public final synchronized void destroy() throws LifecycleException {
        if (state == LifecycleState.DESTROYING || state == LifecycleState.DESTROYED) {
            return;
        }

        setStateAndFireEvent(LifecycleState.DESTROYING);
        try {
            destroy0();
        } catch (Throwable t) {
            setStateAndFireEvent(LifecycleState.FAILED);
            if (t instanceof LifecycleException) {
                throw (LifecycleException) t;
            } else {
                throw new LifecycleException(formatString("Failed to destroy {0}, Error Msg: {1}",
                        toString(), t.getMessage()), t);
            }
        }
        setStateAndFireEvent(LifecycleState.DESTROYED);
    }

    protected abstract void destroy0() throws LifecycleException;

    /*
     * @see
     * ILifecycle#addLifecycleListener(ILifecycleListener)
     */
    @Override
    public void addLifecycleListener(ILifecycleListener listener) {
        listeners.add(listener);
    }

    /*
     * @see
     * ILifecycle#removeLifecycleListener(ILifecycleListener)
     */
    @Override
    public void removeLifecycleListener(ILifecycleListener listener) {
        listeners.remove(listener);
    }

    private void fireLifecycleEvent(LifecycleEvent event) {
        for (Iterator it = listeners.iterator(); it.hasNext();) {
            ILifecycleListener listener = it.next();
            listener.lifecycleEvent(event);
        }
    }

    protected synchronized LifecycleState getState() {
        return state;
    }

    private synchronized void setStateAndFireEvent(LifecycleState newState) throws LifecycleException {
        state = newState;
        fireLifecycleEvent(new LifecycleEvent(state));
    }

    private String formatString(String pattern, Object... arguments) {
        return MessageFormat.format(pattern, arguments);
    }

    /*
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return getClass().getSimpleName();
    }
}

可以看到,抽象類的骨架實現(xiàn)中做了幾件生命周期管理中通用的事情,檢查狀態(tài)之間的轉(zhuǎn)換是否合法(比如說start之前必須要init),設(shè)置內(nèi)部狀態(tài),以及觸發(fā)相應(yīng)的監(jiān)聽者。

抽象類實現(xiàn)了ILifeCycle定義的方法后,又留出了相應(yīng)的抽象方法供其子類實現(xiàn),如上面的代碼所示,其留出來的抽象方法有以下這些:

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;
優(yōu)雅的實現(xiàn)

到目前為止,我們已經(jīng)定義了接口ILifeCycle,以及其骨架實現(xiàn)AbstractLifeCycle,并且增加了監(jiān)聽者機制。貌似我們可以開始寫一個類來繼承AbstractLifecycle,并重寫其定義的抽象方法了,so far so good。

但在開始之前,我們還需要考慮另外幾個問題,

我們的實現(xiàn)類是否對所有的抽象方法都感興趣?

是否每個實現(xiàn)累都需要實現(xiàn)init0, start0, suspend0, resume0, destroy0?

是否有時候,我們的那些有生命的類或者模塊并不支持暫停(suspend),恢復(fù)(resume)?

直接繼承AbstractLifeCycle,就意味著必須實現(xiàn)其全部的抽象方法。
因此,我們還需要一個默認實現(xiàn),DefaultLifeCycle,讓它繼承AbstractLifeCycle,并實現(xiàn)所有抽象方法,但它并不做任何實際的事情, do nothing。只是讓我們真正的實現(xiàn)類來繼承這個默認的實現(xiàn)類,并重寫感興趣的方法。

于是,我們的DefaultLifeCycle就這么誕生了:

public class DefaultLifecycle extends AbstractLifecycle {

    /*
     * @see AbstractLifecycle#init0()
     */
    @Override
    protected void init0() throws LifecycleException {
        // do nothing
    }

    /*
     * @see AbstractLifecycle#start0()
     */
    @Override
    protected void start0() throws LifecycleException {
        // do nothing
    }

    /*
     * @see AbstractLifecycle#suspend0()
     */
    @Override
    protected void suspend0() throws LifecycleException {
        // do nothing
    }

    /*
     * @see AbstractLifecycle#resume0()
     */
    @Override
    protected void resume0() throws LifecycleException {
        // do nothing
    }

    /*
     * @see AbstractLifecycle#destroy0()
     */
    @Override
    protected void destroy0() throws LifecycleException {
        // do nothing
    }

}

對于DefaultLifeCycle來說,do nothing就是其職責。
因此接下來我們可以寫一個自己的實現(xiàn)類,繼承DefaultLifeCycle,并重寫那些感興趣的生命周期方法。

例如,我有一個類只需要在初始化,啟動,和銷毀時做一些任務(wù),那么可以這么寫:

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class SocketServer extends DefaultLifecycle {

    private ServerSocket acceptor = null;
    private int port = 9527;
    /* 
     * @see DefaultLifecycle#init0()
     */
    @Override
    protected void init0() throws LifecycleException {
        try {
            acceptor = new ServerSocket(port);
        } catch (IOException e) {
            throw new LifecycleException(e);
        }
    }

    /* 
     * @see DefaultLifecycle#start0()
     */
    @Override
    protected void start0() throws LifecycleException {
        Socket socket = null;
        try {
            socket = acceptor.accept();
            //do something with socket
            
            
        } catch (IOException e) {
            throw new LifecycleException(e);
        } finally {
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

    /* 
     * @see DefaultLifecycle#destroy0()
     */
    @Override
    protected void destroy0() throws LifecycleException {
        if (acceptor != null) {
            try {
                acceptor.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

這里的ServerSocket中,init0初始化socket監(jiān)聽,start0開始獲取socket連接, destroy0銷毀socket監(jiān)聽。
在這套生命周期管理機制下,我們將會很容易地對資源進行管理,不會發(fā)生資源未關(guān)閉的情況,架構(gòu)和模塊化更加清晰。

尾聲

到這里為止,本文已經(jīng)實現(xiàn)了一個簡易的生命周期管理機制,并給出所有的實現(xiàn)代碼。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/65380.html

相關(guān)文章

  • 金三銀四,2019大廠Android高級工程師面試題整理

    摘要:原文地址游客前言金三銀四,很多同學(xué)心里大概都準備著年后找工作或者跳槽。最近有很多同學(xué)都在交流群里求大廠面試題。 最近整理了一波面試題,包括安卓JAVA方面的,目前大廠還是以安卓源碼,算法,以及數(shù)據(jù)結(jié)構(gòu)為主,有一些中小型公司也會問到混合開發(fā)的知識,至于我為什么傾向于混合開發(fā),我的一句話就是走上編程之路,將來你要學(xué)不僅僅是這些,豐富自己方能與世接軌,做好全棧的裝備。 原文地址:游客kutd...

    tracymac7 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<