倭マン's BLOG

くだらない日々の日記書いてます。 たまにプログラミング関連の記事書いてます。 書いてます。

はじめての幻獣 Griffon 研 (19) : Griffon アプリケーションのライフサイクルを理解する

今回は、前回少し触れた Griffon アプリケーションのライフサイクルをもう少し詳しく見ていきます(一覧)。 詳しくは『Griffon Guide - Reference Documentation』 5. Application Overview を参照。

ライフサイクルの概要?


えー、Griffon アプリケーションのライフサイクルと、各フェーズで行われる処理をとまとめるとこんな感じ:

ちょっと詰め込みすぎかな。 一応、図の説明:

  • 赤い文・黒い文・・・アプリケーション内で行われる処理。 基本的には Griffon アプリケーション開発者はいじらない(Startup MVC グループのインスタンス化は設定可能)。
  • 緑の .groovy ファイル・・・各フェーズで呼び出される .groovy スクリプト。
  • 右端の青い単語・・・発生イベント。

以下でそれぞれを見ていきましょう。

Griffon アプリケーションのライフサイクル


まずはライフサイクルの各フェーズと、内部で行われる処理。 これらは前回も見ました。

フェーズ 説明
Initialize アプリケーションのインスタンス化・設定の読込
Addon の初期化
Startup Startup MVC グループのインスタンス
Ready このフェーズの最後にアプリケーション・フレームを表示
Shutdown アーティファクトのシャットダウン (app.shutdown())
Stop (アプレットのみ) アプレットの終了 (applet.destroy())

少し補足を:

  • Initialize フェーズの「Addon の初期化」は前回書き忘れてましたが、これは使用しているプラグインの初期化です。
  • Startup フェーズの「Startup MVC グループインスタンス化」は、アプリケーション・フレームのようなアプリケーションの開始時に作成されるべき MVC グループのインスタンスを作成します。 これが実行される前にはどの MVC グループのインスタンスにもアクセスすることはできません。

Startup MVC グループは

  • $basedir/griffon-app/conf/Application.groovy

にて設定できます。

スクリプト


各フェーズで行いたい処理がある場合は、

  • $basedir/griffon-app/lifecycle

フォルダに配置されている、対応する名前の .groovy ファイル内に処理を記述します。

  • Initialize.groovy
  • Startup.groovy
  • Ready.groovy
  • Shutdown.groovy
  • Stop.groovy

イベント


Griffon で定義されているイベントには大きく分けて次の2つがあります:

  • ライフサイクル・イベント
  • アーティファクト・イベント

独自のイベントも作成できるようですが、ここでは触れません。

ライフサイクル・イベント

ライフサイクルの各フェーズに関連するイベントには以下のようなものがあります。

フェーズ 開始時 終了時
Initialize - BootstrapEnd[app]
Startup StartupStart[app] StartupEnd[app]
Ready ReadyStart[app] ReadyEnd[app]
Shutdown ShutdownStart[app] -
Stop - -
  • 前節の .groovy スクリプトと違って、これらのイベントはアスペクト・プログラミングでの処理の織り込みのように、各フェーズの開始・終了時に処理を追加するときに使用します。
  • [] 括弧で示しているのは、メソッドもしくはクロージャによって定義したイベント・ハンドラに渡されるオブジェクトです。 イベント・ハンドラに関しては後ほど。
  • 『Griffon Guide - Reference Documentation』には Shutdown.groovy は ShutdownStart イベントよりも前に実行されると書かれていますが、実際に実行してみると実行順序は逆になってます。

アーティファクト・イベント

上記以外にもアーティファクトMVC, Service オブジェクトなど)に関するイベントも定義されています:

  • NewInstance[klass, type, instance]・・・type は 'model', 'view', 'controller', 'service' などの String オブジェト。
  • LoadAddonsStart[app]
  • LoadAddonsEnd[app, addons]
  • LoadAddonStart[name, addon, app]
  • LoadAddonEnd[name, addon, app]

[]はライフサイクル・イベントのときと同じ意味です。 LoadAddons/LoadAddon イベントは Initialize フェーズにて発生します。 一方、NewInstance イベントは(Startup MVC グループや Service の場合)Startup フェーズにて発生します。

イベント・ハンドラ


次は前節のイベントに応じて処理を実行するイベント・ハンドラの定義方法を見ていきます。 『Griffon Guide - Reference Documentation』にはイベント・ハンドラが満たすべき条件がいろいろ箇条書きにされてますが、ここではそれらは気にせずに次の2つの方法だけを見ていきます:

  • Controller にクロージャ型プロパティを定義する
  • Events.groovy スクリプトに処理を定義する

Controller にクロージャ型プロパティを定義する

まずは Controller にクロージャ型プロパティを定義する方法。 プロパティ名は on《イベント名》とします:

class FunctionPlotterController {

    def onStartupEnd = { app -> /* Startup フェーズ終了時の処理 */ }

    def onReadyStart = { app -> /* Ready フェーズ開始時の処理 */ }
    def onReadyEnd  = { app -> /* Ready フェーズ終了時の処理 */ }

    def onShutdownStart = { app -> /* Shutdown フェーズ開始時の処理 */ }
}

Controller はどんなに早くても Startup フェーズまでインスタンスが作成されないので、BootstrapEnd, StartupStart イベントに対応するイベント・ハンドラを定義していてもイベントを受け取りません

Events.groovy スクリプトに処理を定義する

次は Events.groovy スクリプトを作成して処理を記述する方法。 Events.groovy ファイルは「$basedir/griffon-app/conf」フォルダに作成します:

  • $basedir/griffon-app/conf/Events.groovy

内容は次のような感じ:

onBootstrapEnd = { app -> /* Initialize フェーズ終了時の処理 */ }

onStartupStart = { app -> /* Startup フェーズ開始時の処理 */ }
onStartupEnd  = { app -> /* Startup フェーズ終了時の処理 */ }

onReadyStart = { app -> /* Ready フェーズ開始時の処理 */ }
onReadyEnd  = { app -> /* Ready フェーズ終了時の処理 */ }

onShutdownStart = { app -> /* Shutdown フェーズ開始時の処理 */ }

Controller の場合と大体同じですが、def キーワードを付けると処理が実行されません*1

Java Swing Hacks ―今日から使える驚きのGUIプログラミング集

Java Swing Hacks ―今日から使える驚きのGUIプログラミング集

*1:Script オブジェクトの main() メソッド内のローカル変数と解釈されるのかな?