最初にそれについて話しましょう
最近、私は国内のオープンソースMySQLデータベースミドルウェアを研究しています。コードの最新バージョンをEclipseに引き下げ、起動し、さまざまなテストとコードトラッキングを行った後。それを使用した後に閉じたいとき、私はその停止クラスを引き出して実行したいです。このクラスでは、次のコード行のみが書かれていることがわかったので、すぐに多くの傷を負っていると感じました。
public static void main(string [] args){system.out.println(new date() + "、server shutdown!"); }このミドルウェアが起動して実行されると、リスニングが有効になり、多くのスレッドが実行を開始し、多くのソケット接続があります。しかし、それをオフにするエレガントな方法はありません。そのため、必死になって、私は日食の小さな赤い点にしか行けず、VMを強制的に止めました。
優れたアーキテクチャ、モジュール性、明確な構造、特にサーバーのようなソフトウェアを備えたソフトウェアの場合、一連のライフサイクル管理メカニズムを持つことが非常に重要です。各モジュールのライフサイクルを管理できるだけでなく、リソースを失うことなくソフトウェア全体を開始および停止するときにもエレガントになる可能性があります。
ライフサイクルメカニズムの簡単な実装
ライフサイクル状態
モジュールのライフサイクルの状態には、一般的に次のものがあります。
新生児 - >初期化 - >初期化完了 - >初期化 - >初期化完了 - > initial-> initialization-> dapusing-> recovering-> recovering-> Destroling-> Destroling-> Destrying。任意の状態間の変換が失敗した場合、それは別の状態、つまり障害に入ります。
これを行うには、以下に示すように、列挙クラスを使用してこれらの状態を列挙できます。
public enum lifecycleState {new、// Newsen初期化、初期化、// initialize start、Starting、// Start Suspending、suspended、//一時停止、再開、//破壊、破壊、// restore failed; // failed}}インタフェース
以下に示すように、ライフサイクルのさまざまな行動規範には、定義するインターフェイスも必要です。
パブリックインターフェイスilifecycle { / ** *初期化 * * @throws lifecycleexception * / public void init()throws lifecycleexception; / ** * start * * @throws lifecycleexception */ public void start()throws lifecycleexception; / ** * PAUSE * * @Throws LifeCycleException */ public void Suspend()LifeCycleExceptionをスローします。 / ** *回復 * * @throws lifecycleexception */ public void resume()throws lifecycleexception; / ** * Destroy * * @Throws LifeCycleException */ public void Destroy()Throws LifeCycleException; / ** *ライフサイクルリスナーを追加 * * @paramリスナー */ public void addlifecyclelistener(ilifecyclelistenerリスナー); / ** *ライフサイクルリスナーを削除 * * @paramリスナー */ public void removelifecyclelistener(ilifecyclelistenerリスナー);}ライフサイクル状態の移行が発生した場合、特定のタイプのイベントに興味のあるリスナーをトリガーする必要がある場合があるため、ilifecycleはリスナーを追加および削除する2つの方法も定義します。それらは次のとおりです。およびpublic void removelifecyclelistener(ilifecyclelistenerリスナー);
リスナーは、以下に示すように、インターフェイスによって行動の規範を定義します。
パブリックインターフェイスilifecyclelistener { / ***ライフサイクルイベントを処理** @paramイベントライフサイクルイベント* / public void lifecyclevent(lifecycleevent event);}ライフサイクルイベントは、以下に示すように、LifecycleEventによって表されます。
パブリックファイナルクラスLifecycleEvent {private Lifecyclestate State; Public LifecycleEvent(Lifecyclestate State){this.state = state; } / ** * @The State * / Public LifeCyclestate getState(){return state; }}スケルトンの実装
iLifecycleインターフェイスを使用すると、このインターフェイスを実装するクラスは、ライフサイクル管理オブジェクトとして使用されます。このクラスは、ソケットリスニングサービスであるか、特定のモジュールなどを表すことができます。それは言うことができますが、各ライフサイクル管理オブジェクトは、次のようなライフサイクルのさまざまな段階でいくつかの共通の動作を持つことを考慮すると、
独自のライフサイクル状態を設定して、状態の移行がロジックに準拠しているかどうかを確認して、ライフサイクルの状態が変化したことをリスナーに通知します。したがって、ilifecycleのスケルトンの実装として抽象クラスの抽象的な抽象的なを提供することは非常に重要です。この抽象クラスは、ilifecycleで定義されたすべてのインターフェイスメソッドを実装し、サブクラス実装に対応する抽象的なメソッドを追加します。 AbstractLifeCycleは次のように実装できます。
public abstract class abstractlifecycleはilifecycle {private list <ilifecyclelistener> listeners = new copyonwritearraylist <ilifecyclelistener>(); / ***状態は現在のライフサイクル状態を表しています*/ private lifecyclestate state = lifecyclestate.new; / * * @see ilifecycle#init() */ @override public final synchronized void init()throws lifecycleexception {if(state!= lifecyclestate.new){return; } setStateandfireevent(lifecyclestate.initializing); {init0(); } catch(throwable t){setstateandfireevent(lifecyclestate.failed); if(t instanceof lifecycleexception){throw(lifecycleexception)t; } else {throw new LifeCycleException(formattring( "{0}、error msg:{1}"、toString()、t.getMessage()、t); }} setstateandfireevent(lifecyclestate.Initialized); }保護された抽象void init0()はライフサイクルエクセプトをスローします。 / * * @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( "{0}を起動しなかった)、エラーmsg:{1}"、toString()、t.getMessage()、t); }} setstateandfireevent(lifecyclestate.started); }保護された抽象void start0()スローlifecycleexception; / * * @see ilifecycle#suspend() */ @override public final synchronized void suspend()throws lifecycleexception {if(state == lifecyclestate.suspending || state == lifecyclestate.suspedend){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(formattring( "{0}を停止しなかった)、エラーmsg:{1}"、toString()、t.getMessage()、t); }} setStateandfireevent(lifecyclestate.spended); }保護された抽象void suspend0()はlifecycleexceptionをスローします。 / * * @see ilifecycle#resume() */ @override public final synchronized void resume()throws lifecycleexception {if(state!= lifecyclestate.suspedend){return; } setStateandfireevent(lifecyclestate.resuming); try {resume0(); } catch(throwable t){setstateandfireevent(lifecyclestate.failed); if(t instanceof lifecycleexception){throw(lifecycleexception)t; } else {throw new LifeCycleException(formattring( "{0}を再開できなかった)、エラーmsg:{1}"、toString()、t.getMessage()、t); }} setstateandfireevent(lifecyclestate.resumed); }保護された抽象void resume0()スローlifecycleexception; / * * @see ilifecycle#Destroy() */ @Override public final synchronized void destroy()throws lifecycleexception {if(state == lifecyclestate.destroying || state == lifecyclestate.destroyed){return; } setStateandfireevent(lifecyclestate.destroing); try {destroy0(); } catch(throwable t){setstateandfireevent(lifecyclestate.failed); if(t instanceof lifecycleexception){throw(lifecycleexception)t; } else {throw new lifeCycleException(formattring( "{0}を破壊しなかった)、エラーmsg:{1}"、toString()、t.getMessage())、t); }} setstateandfireevent(lifecyclestate.destroyed); }保護された抽象void destroy0()はライフサイクルエクセプトをスローします。 / * * @see * ilifecycle#addlifecyclelistener(ilifecyclelistener) */ @Override public void addlifecyclelistener(ilifecyclelistenerリスナー){ristens.add(リスナー); } / * * @see * ilifecycle#removelistener(ilifecyclelistener) * / @Override public void removelifecyclelistener(ilifecyclelistenerリスナー){ristens.remove(リスナー); } private void firelifecycleevent(lifecycleevent event){for(iterator <ilifecyclelistener> it = ristens.iterator(); it.hasnext(); listener.lifecycleevent(event); }}保護された同期ライフサイクレステートgetState(){return state; } private synchronized void setstateandfireevent(lifecyclestate newstate)throws lifecycleexception {state = newstate; FireLifeCycleEvent(New LifeCycleEvent(STATE)); } private string formattring(string pattern、object ... arguments){return messageformat.format(pattern、arguments); } / * * @see java.lang.object#toString() * / @Override public String toString(){return getClass()。getSimplename(); }}抽象クラスのスケルトンの実装は、ライフサイクル管理でいくつかの一般的なことを行い、状態間の移行が合法か(たとえば、開始前にinitでなければならない)、内部状態を設定し、対応するリスナーをトリガーするかどうかを確認することがわかります。
抽象クラスがilifecycleで定義された方法を実装した後、サブクラスが実装するための対応する抽象的な方法を残します。上記のコードに示されているように、除外された抽象的なメソッドには以下が含まれます。
保護された抽象void init0()はライフサイクルエクセプトをスローします。保護された抽象void start0()はライフサイクルエクセプトをスローします。保護された抽象void suspend0()はライフサイクルエクセプトをスローします。保護された抽象void resume0()はライフサイクルエクセプトをスローします。保護された抽象的なvoid Destroy0()はライフサイクルエクセプトをスローします。
エレガントな実装
これまでのところ、インターフェイスilifecycleを定義しており、その骨格はAbstractLifecycleを実装し、リスナーメカニズムを追加しました。クラスの作成を開始して、抽象的なライフサイクルを継承し、これまでに定義する抽象的な方法を書き直すことができるようです。
しかし、開始する前に、他のいくつかの問題を考慮する必要があります。
実装クラスはすべての抽象的なメソッドに興味がありますか?
各実装は、init0、start0、suspend0、resume0、destroy0、destroy0を実装する必要がありますか?
私たちの生きているクラスやモジュールがサスペンションや回復をサポートしないことがありますか?
AbstractLifeCycleを直接継承すると、すべての抽象的なメソッドを実装する必要があることを意味します。
そのため、デフォルトの実装、DefaultLifeCycleが必要であり、AbstractLifeCycleを継承し、すべての抽象的なメソッドを実装する必要がありますが、実用的なことは何もしません。実際の実装クラスをこのデフォルトの実装クラスを継承し、関心のある方法をオーバーライドさせてください。
それで、私たちのDefaultLifecycleが生まれました:
public class defaultlifecycleはabstractlifecycle { / * * @see abstractlifecycle#init0() * /@overrideプロテクションvoid init0()lifecycleexception {// do nothing} / * * @sectlifecycle#start0() * /@overide stared started0 #suspend0() */ @overrideプロテクションvoid suspendinternal()throws lifecycleexception {// do nothing}/ * * @see abstractlifecycle#resume0() */ @overrideプロテクションボイドresume0()スローLifeCycleException {// void destroy0()throws lifecycleexception {//何もしない}} DefaultLifeCycleの場合、その責任は何もありません。
次に、独自の実装クラスを作成し、DefaultLifeCycleを継承し、これらのライフサイクルの関心方法を書き直すことができます。
たとえば、初期化、起動、破壊中にいくつかのタスクを実行する必要があるクラスがあるため、次のように書くことができます。
java.io.ioexception; Import java.net.serversocket; Import java.net.socket; public class socketserverはdefaultlifecycle {private serversocket Acceptor = null; Private int port = 9527; / * * @See DefaultLifeCycle#init0() */ @Override Protected void init0()throws lifecycleException {try {accedor = new Serversocket(port); } catch(ioException e){新しいlifecycleexception(e); }} / * * @see defaultlifecycle#start0() * / @overrideプロテクションvoid start0()throws lifecycleexception {socket socket = null; try {socket = accedor.accept(); //ソケットで何かを行う} catch(ioexception e){新しいlifecycleexception(e); }最後に{if(socket!= null){try {socket.close(); } catch(ioException e){// todo auto-fenated catch block e.printstacktrace(); }}}}}} / * * @see defaultlifecycle#Destroy0() * / @Override Protected void Destroy0()throws lifecycleexception {if(accedor!= null){try {accedor.close(); } catch(ioException e){// todo auto-fenated catch block e.printstacktrace(); }}}}ここのServersocketでは、init0がソケットリスニングを初期化し、Start0がソケット接続の取得を開始し、Destroy0がソケットリスニングを破壊します。
このライフサイクル管理メカニズムの下では、リソースを簡単に管理し、リソースのシャットダウンがなく、アーキテクチャとモジュール性がより明確になります。
終わり
これまでのところ、この記事はシンプルなライフサイクル管理メカニズムを実装し、すべての実装コードを与えています。その後、すべてのソースコードがGitHubに配置されます。この記事の更新に注意してください。