LastaFluteのパッケージ構成

LastaFluteのパッケージや重要なクラス、リソースについて。

LastaFlute

とりあえずこんな感じです

架空のプロジェクトである、マルチプロジェクト構成のMaihamaプロジェクトの Dockside ドメイン (Webアプリ) を想定して説明します。これらは、LastaFlute の Example 実装として公開されています。

e.g. Maihamaプロジェクトのパッケージ構成 @Directory
lastaflute
 |-src/main/java
 |-src/main/resources
 |  |-jdbc.xml              // ConnectionPoolなどの定義: 情報はconfigから取得
 |  |-jta+transactionManager.xml // RomanticTransactionのオーバーライド
 |  |-jta+userTransaction.xml    // トランザクションフックのオーバーライド
 |  |-lastaflute_assist.xml // AssistantDirector や Config など横断アシスト
 |  |-lastaflute_core.xml   // coreのコンポーネントを定義する xml
 |  |-lastaflute_db.xml     // DB周りのコンポーネントを定義する xml
 |  |-lastaflute_web.xml    // Web周りのコンポーネントを定義する xml
 |  |-lastaflute.xml        // アプリが include する、いわゆる "入り口xml"
 |  |-lastafw_creator.xml       // LastaFluteで拡張するcreator定義
 |  |-lastafw_customizer.xml    // LastaFluteで拡張するcustomizer定義
 |  |-selectable_datasource.xml // SelectableDataSourceの定義 (オプション)
 |-...

maihama-base // ベースプロジェクト (親pomやドキュメントなど)
 |-etc
 |-modeling
 |-pom.xml
 ... // パッケージは存在しない

maihama-common // commonプロジェクト (DBFluteも含む)
 |-src/main/java // Maihamaプロジェクト共通クラスたち
 |  |-org.docksidestage // アプリのドメインパッケージ
 |     |-app // アプリ間で共通のアプリクラスのパッケージ ☆ホット&規約デプロイ
 |     |  |-logic // アプリ間で再利用するLogicを配置するパッケージ
 |     |  |  |-.gitkeep // Maihamaでは何もない
 |     |  |-web // アプリをまたぐ共有のweb部品だが、commonではActionは作らないこと
 |     |    |-base
 |     |      |-login
 |     |      |  |-MaihamaLoginAssist // Maihama固有のログインAssist
 |     |      |-paging
 |     |      |  |-PagingNavi // ページングナビゲーションのためのクラス
 |     |      |-MaihamaBaseAction // Maihama全体のActionのスーパークラス
 |     |
 |     |-bizfw // 業務的なフレームワークを作るパッケージ (Di xmlに登録)
 |     |  |-.gitkeep // 作ったら、app.xml or bizfw.xml (自分で作成) に登録
 |     |
 |     |-dbflute // DBFluteのパッケージ (DBFluteなので説明は割愛)
 |     |  |-allcommon
 |     |  |-...
 |     |
 |     |-mylasta // Maihama固有のLastaFlute対応クラスのパッケージ
 |        |-action // Actionに関するパッケージ
 |        |  |-MaihamaLabels   // maihama_label 対応のクラス (自動生成)
 |        |  |-MaihamaMessages // maihama_message 対応のクラス (自動生成)
 |        |  |-MaihamaUserBean // ログインしているユーザー情報のBean
 |        |-direction // LastaFluteをMaihama風にするパッケージ
 |           |-sponsor // AssistantDirectorで設定する処理を切り出したクラスなど
 |           |  |-MaihamaActionAdjustmentProvider // Action微調整
 |           |  |-MaihamaApiFailureHook // APIリクエストの例外発生時の共通Hook
 |           |  |-MaihamaCookieResourceProvider // クッキーのリソース
 |           |  |-MaihamaCurtainBeforeListener // アプリ起動直前リスナー
 |           |  |-MaihamaListedClassificationProvider // リスト表示される区分値
 |           |  |-MaihamaMailDeliveryDepartmentCreator // メール配信部署の作成
 |           |  |-MaihamaSecurityResourceProvider // 暗号化リソースなど
 |           |  |-MaihamaTimeResourceProvider // 現在日時リソース
 |           |  |-MaihamaUserLocaleProcessProvider // ユーザーロケール処理
 |           |  |-MaihamaUserTimeZoneProcessProvider // ユーザータイムゾーン処理
 |           |
 |           |-MaihamaConfig // maihama_config 対応クラス(自動生成)
 |           |-MaihamaEnv    // maihama_env 対応クラス(自動生成)
 |           |-MaihamaFwAssistantDirector // ☆Lastaの現場フィットを司る
 |
 |-src/main/resources  // dbflute.xml や properties など
 |  |-dbflute.xml         // DBFluteの xml (自動生成)
 |  |-lasta_di.properties // Lasta Diの微調整properties (SmartDeploy設定など)
 |  |-maihama_config.properties  // Maihamaプロジェクト共通の通常コンフィグ
 |  |-maihama_env.properties     // Maihamaプロジェクト共通の環境依存コンフィグ
 |  |-maihama_env_integration.properties // 環境依存コンフィグの結合用
 |  |-maihama_env_production.properties  // 環境依存コンフィグの本番用
 |  |-maihama_label.properties   // Maihamaプロジェクト共通のラベルリソース
 |  |-maihama_message.properties // Maihamaプロジェクト共通のメッセージリソース
 |
 |-src/allpackage/resources // mavenでpackageするときの共通リソース
 |  |-.gitkeep // Maihamaではまだ何もない
 |
 |-src/integration/resources // 結合環境のリソース
 |  |-maihama_env.properties // 結合環境の環境依存コンフィグ
 |    // ※ここに、Di xml や "envではないproperties" は置かないこと
 |
 |-src/production/resources  // 本番環境のリソース
 |  |-maihama_env.properties // 本番環境の環境依存コンフィグ
 |    // ※ここに、Di xml や "envではないproperties" は置かないこと
 |
 |-...

maihama-dockside // アプリプロジェクト (Webアプリ)
 |-src/main/java // Docksideのクラスたち
 |  |-org.docksidestage
 |     |-app // Actionなど、アプリクラスのパッケージ ☆ホット&規約デプロイ
 |     |  |-logic // 画面間で再利用するLogicを配置するパッケージ
 |     |  |  |-.gitkeep // Docksideでは何もない
 |     |  |-web   // Web関連のクラスを配置するパッケージ (Actionクラスなど)
 |     |     |-base   // Actionなどのスーパークラスを配置するパッケージ
 |     |     |  |-login
 |     |     |  |  |-DocksideLoginAssist // Docksideに合わせたLoginAssist
 |     |     |  |-DocksideBaseAction // 全てのActionが継承するスーパークラス
 |     |     |  |-DocksideHeaderBean // ヘッダー表示のデータを格納するBean
 |     |     |-signin // ログイン画面 (Action, Form, WebBeanなど)
 |     |     |  |-SigninAction // ログイン画面のAction
 |     |     |  |-SigninForm   // ログイン画面のActionForm
 |     |     |-mypage // マイページ画面 (Action, Form, WebBeanなど)
 |     |     |  |-MypageAction // マイページ画面のAction
 |     |     |  |-...
 |     |     |-...
 |     |
 |     |-mylasta // Dockside固有のLastaFlute対応クラスのパッケージ
 |        |-action      // Action関連の自動生成クラスや継承クラス、アノテーションなど
 |        |  |-DocksideHtmlPath // HTMLテンプレートのパス定義クラス (自動生成)
 |        |  |-DocksideLabels   // dockside_label 対応クラス (自動生成)
 |        |-direction   // LastaFluteをMaihamaプロジェクト風にするところ☆
 |        |  |-DocksideConfig // dockside_config 対応クラス(自動生成)
 |        |  |-DocksideEnv    // dockside_emv 対応クラス(自動生成)
 |        |  |-DocksideFwAssistantDirector // Lastaの現場フィットを司る
 |        |
 |        |-mail     // MailFluteのテンプレートから自動生成されたクラスのパッケージ
 |        |-template // 汎用テンプレートから自動生成されたクラスのパッケージ
 |
 |-src/main/resources  // app.xml, dockside_env.properties など
 |  |-app.xml   // Lasta Diが読み込む最初のxml
 |  |-dockside_config.properties  // Docksideアプリの通常コンフィグ
 |  |-dockside_env.properties     // Docksideアプリの環境依存コンフィグ
 |  |-dockside_env_integration.properties // 環境依存コンフィグの結合用
 |  |-dockside_env_production.properties  // 環境依存コンフィグの本番用
 |  |-dockside_label.properties   // Docksideアプリのラベルリソース
 |  |-dockside_message.properties // Docksideアプリのメッセージリソース
 |  |-lastaflute_director.xml // Dockside固有の AssistantDirector や config
 |  |-logback.xml // Logbackの設定 (ローカル環境用なのでDEBUG)
 |-...

Di xml の階層構造

Lasta Di のページを参考に。

アプリで作成する Di xml と、その周辺の xml はこのような感じ。

e.g. Di xml Hierarchy, embedded color: red for Lasta Di, blue for LastaFlute @app.xml
...Reading lasta_di.xml
...Reading   redefiner.xml
...Reading   ...
...Reading app.xml // *アプリで作成 (固定の名前)
...Reading   convention.xml
...Reading     embedded_convention.xml
...Reading   dbflute.xml // *アプリで作成 (自動生成、ひとつのスキーマでひとつ)
...Reading     rdb.xml
...Reading       jta.xml
...Reading         jta+userTransaction.xml
...Reading         jta+transactionManager.xml
...Reading       jdbc.xml
...Reading         jta.xml (recycle)
...Reading         lastaflute_assist.xml
...Reading           lastaflute_director.xml // *アプリで作成 (固定の名前)
...Reading       tx_aop.xml
...Reading         jta.xml (recycle)
...Reading   lastaflute.xml
...Reading     lastaflute_core.xml
...Reading     ...

Maihamaプロジェクトのプロジェクト構成

そもそものプロジェクト構成は、別ページにて紹介しています。

おおまかな特徴

おおまかな特徴は以下の通り。

階層重視
フレームワーク、プロジェクト共通、ドメイン共通、それぞれの画面、というように領域を明確に分け、スーパークラスもその階層ごとに存在しています。 たまに空っぽに近いスーパークラスもいますが、いずれ必要になる可能性があるため最初から存在します。
設定ファイルも共通化
propertiesなども、継承できるようにして共通のものはcommonで管理できるようにしています。
xmlでコンフィグ管理しない
環境ごとに切り替えるのは .properties ファイルだけで、xmlを切り替えるようなことはしない。
LastaFluteの現場フィットをAssistantDirectorに集中
xmlをコピーして拡張するというようなことがないように、LastaFlute側であらかじめ拡張ポイントを用意しています。 アプリは AssistantDirector だけを拡張して、LastaFluteを現場の要件にフィットさせます。
ホットデプロイ対象とそうでないものをパッケージ分け
HotDeployトラブル (LinkageError や、不思議な ClassCastException など) を避け、HotDeployのメリットを最大限享受するため、ホットデプロイ対象のクラスとそうでないクラスを明確にパッケージ分けしています。

現場フィットを一元管理

LastaFluteをアプリに適用させるための設定や調整 (つまり現場フィット) などは、AssistantDirector経由で行います。 決して、xmlをコピー拡張したりはしません。

e.g. AssistantDirector で現場フィット @Directory
public abstract class MaihamaFwAssistantDirector extends CachedFwAssistantDirector {

    // ===================================================================================
    //                                                                           Attribute
    //                                                                           =========
    @Resource
    protected MaihamaConfig maihamaConfig;

    // ===================================================================================
    //                                                                              Assist
    //                                                                              ======
    @Override
    protected void prepareAssistDirection(FwAssistDirection direction) {
        direction.directConfig(nameList -> setupAppConfig(nameList), "maihama_config.properties", "maihama_env.properties");
    }

    protected abstract void setupAppConfig(List<String> nameList);

    // ===================================================================================
    //                                                                               Core
    //                                                                              ======
    @Override
    protected void prepareCoreDirection(FwCoreDirection direction) {
        // this configuration is on maihama_env.properties because this is true only when development
        direction.directDevelopmentHere(maihamaConfig.isDevelopmentHere());

        // titles of the application for logging are from configurations
        direction.directLoggingTitle(maihamaConfig.getDomainTitle(), maihamaConfig.getEnvironmentTitle());

        ...
    }
    ...
}

appはホット&規約デプロイ

appパッケージ配下は、ホットデプロイであり、かつ、規約デプロイです。

Action や Form などは、修正したら再起動せずにアプリに反映されます。 また、Di xmlに登録することなく、クラス名の規約に従っていれば自動で Lasta Di のコンポーネントとして登録されます。

Action
app.webパッケージ配下の任意の場所に、XxxAction
Form
app.webパッケージ配下の任意の場所に、XxxForm

TODO jflute

ホットデプロイ対象を明確に

明確なパッケージ分け

HotDeployトラブル (LinkageError や、不思議な ClassCastException など) を避け、HotDeployのメリットを最大限享受するため、ホットデプロイ対象のクラスとそうでないクラスを明確にパッケージ分けしています。

ごちゃませにするとHotDeployトラブルがおきやすく、最初から分けていた方が世話ないという思想です。 (ディベロッパーは、appの外からappの中のクラスを参照してはいけないと覚えるだけ)

e.g. ホットデプロイ対象を明確に @Directory
maihama-common
/src/main/java
 |
 |-org.docksidestage
 |  |-app       // ルートパッケージ (ホットデプロイ、Actionクラスなど)
 |  |  |-...
 |  |-dbflute   // DBFluteのパッケージ (フレームワークなど)
 |  |  |-...
 |  |-mylasta   // Maihamaの現場フィットパッケージ
 |  |  |-...

maihama-dockside
/src/main/java
 |
 |-org.dbflute.maihama
 |  |-app       // ルートパッケージ (ホットデプロイ、Actionクラスなど)
 |  |  |-...
 |  |-mylasta   // Docksideの現場フィットパッケージ
 |  |  |-...

DBFluteのクラスも外に出します。DBFluteはそもそも HotDeploy に対応していません。バッチを叩いてまで HotDeploy である必要はないと考えるからです。厳密には、Exクラスへの追加もありますが、頻度は少ないため割り切っています。

逆参照はダメ

mylasta や dbflute などのホットデプロイ対象ではないパッケージから、appのクラスを参照してはいけません。 ホットデプロイが効かなくなってしまいます。また、それを意識することで、参照方向を規約的に統一することができます。