SAFluteのパッケージ構成

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

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

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

e.g. Maihamaプロジェクトのパッケージ構成 @Directory

saflute // SAFlute本体 (ソースコード)
 |-src/main/java
 |  |-org.dbflute.saflute
 |  |  |-core           // SAFluteのcoreとなるパッケージ
 |  |  |  |-direction   // SAFlute全体のディレクションを司る
 |  |  |  |  |-OptionalAssistDirection.java // Configのディレクション
 |  |  |  |  |-OptionalCoreDirection.java   // Coreのディレクション
 |  |  |  |
 |  |  |  |-exception   // SAFluteの基本の共通クラスたち
 |  |  |  |-interceptor // SeasarのInterceptorの拡張クラスたち
 |  |  |  |-json        // JSONハンドリングのクラスたち
 |  |  |  |-magic       // 魔法のようなクラスたち (スレッドキャッシュなど)
 |  |  |  |-message     // メッセージハンドリングのクラスたち
 |  |  |  |-security    // セキュリティ関連のクラスたち (Cipherなど)
 |  |  |  |-smartdeploy // Seasarのスマートデプロイの拡張クラスたち
 |  |  |  |-time        // 時間ハンドリングのクラスたち (現在日時取得など)
 |  |  |  |-util        // ちょっとしたUtilクラスたち (ContainerUtilなど)
 |  |  |-db             // SAFluteのDB関連のパッケージ
 |  |  |  |-dbflute     // SAFluteのDBFlute拡張クラス
 |  |  |  |  |-OptionalDBFluteDirection.java // DBFluteのディレクション
 |  |  |  |
 |  |  |  |-jta         // JTAの拡張クラスたち (微調整クラス)
 |  |  |-web            // SAFluteのWeb関連のパッケージ
 |  |  |  |-action      // Action (SAStruts) 関連のパッケージ
 |  |  |  |  |-api         // API (Ajax や JSON など) のやり取りを司るクラスたち
 |  |  |  |  |-callback    // ActionCallback を司るクラスたち
 |  |  |  |  |-exception   // Action関連の共通例外クラスたち
 |  |  |  |  |-interceptor // Action関連のInterceptor関連クラスたち
 |  |  |  |  |-login       // ログインに関するクラスたち (UserBeanなど)
 |  |  |  |  |-message     // メッセージに関するクラスたち (MessageResourceなど)
 |  |  |  |  |-processor   // RequestProcessorに関するクラスたち☆
 |  |  |  |  |  |-...
 |  |  |  |  |  |-ActionMultipartRequestHandler.java // DoS対策など
 |  |  |  |  |  |-ActionMappingWrapper.java // ForwardもSAFlute風にしたりなど
 |  |  |  |  |  |-ActionRequestProcessor.java   // RequestProcessorの拡張
 |  |  |  |  |  | // ☆これはハイパー大事
 |  |  |  |  |  | // (struts-config.xmlにて定義される)
 |  |  |  |  |  |-GodHandableActionWrapper.java // GodHandを実現する拡張
 |  |  |  |  |  | // ☆これもミラクル大事
 |  |  |  |  |  | // (ActionRequestProcessorにてnewされる)
 |  |  |  |  |  |-...
 |  |  |  |  |-response   // Actionの戻り値 (Response) に関するクラスたち
 |  |  |  |  |-...
 |  |  |  |  |-ActionResolver.java  // ActionクラスとURLのマッピングなどを司る
 |  |  |  |  |-OptionalActionDirection.java  // Actionのディレクション
 |  |  |  |  |-RootAction.java         // Actionの根っこスーパークラス
 |  |  |  |  |-TypicalBaseAction.java  // Actionの典型的スーパークラス
 |  |  |  |  |-...
 |  |  |  |
 |  |  |  |-servlet     // Servlet 関連のパッケージ
 |  |  |  |  |-cookie   // Cookieに関するクラスたち (CookieManagerなど)
 |  |  |  |  |-filter   // 独自のServletFilterたち
 |  |  |  |  |  |-RequestLoggingFilter.java // デバッグログ大事ですよ (web.xml)
 |  |  |  |  |  |-RequestRoutingFilter.java // RoutingFilterの拡張 (web.xml)
 |  |  |  |  |-request  // Requestに関するクラスたち (RequestManagerなど)
 |  |  |  |  |-session  // Sessionに関するクラスたち (SessionManagerなど)
 |  |  |  |  |-taglib   // Taglibに関するクラスたち (MappingFormTagなど)
 |  |  |  |  |-ContainerManagementServlet.java // S2ContainerServletの拡張
 |  |  |  |  |-OptionalServletDirection.java // Servletのディレクション
 |  |  |  |
 |  |  |  |-task        // Task (バッチ) 関連のパッケージ
 |  |  |  |  |-callback    // TaskでもActionCallbackみたいにするクラスたち
 |  |  |  |  |-interceptor // TaskでもActionみたいにいろいろできるクラスたち
 |  |  |  |  |-BatchBaseTask.java         // 全てのTaskのスーパークラス
 |  |  |  |  |-OptionalTaskDirection.java // Taskのディレクション
 |  |  |  |
 |-src/main/resources
 |  |-jta+UserTransaction.dicon // トランザクションフックのオーバーライド dicon
 |  |-saflute_assist.dicon // アプリが ++.dicon で AD を追加する dicon
 |  |-saflute_core.dicon   // coreのコンポーネントを定義する dicon
 |  |-saflute_db.dicon     // DB周りのコンポーネントを定義する dicon
 |  |-saflute_web.dicon    // Web周りのコンポーネントを定義する dicon
 |  |-saflute.dicon // アプリが include する、いわゆる "入り口dicon"
 |-...

maihama-base           // ベースプロジェクト (親pomやドキュメントなど)
 |-...

maihama-common         // commonプロジェクト (DBFluteも含む)
 |-src/main/java       // Maihamaプロジェクト共通クラス
 |  |-org.dbflute.maihama
 |     |-dbflute           // DBFluteのパッケージ (DBFluteなので説明は割愛)
 |     |  |-allcommon
 |     |  |-...
 |     |-projectfw         // Maihamaプロジェクトのフレームワークパッケージ
 |        |-core           // SAFluteのcoreを拡張したクラスなど
 |        |  |-direction   // SAFluteをMaihamaプロジェクト風にするところ☆
 |        |     |-sponsor  // AssistantDirectorで設定する処理を切り出したクラスなど
 |        |     |-MaihamaConfig.java // maihama_config 対応クラス(自動生成)
 |        |     |-MaihamaEnv.java    // maihama_env 対応クラス(自動生成)
 |        |     |-MaihamaFwAssistantDirector.java // SAFluteの現場フィットを司る
 |        |       // ☆これが最強に大事
 |        |       // (各ドメインが継承して微調整オーバーライドする)
 |        |
 |        |-web           // SAFluteのwebを拡張したクラスなど
 |           |-action          // SAFluteのwebを拡張したクラスなど
 |           |-login           // ログインに関する
 |           |-paging          // SAFluteのwebを拡張したクラスなど
 |
 |-src/main/resources  // convention.dicon, dbflute.dicon など
 |  |-convention.dicon    // Seasarのスマートデプロイのルートパッケージを決める dicon
 |  |-creator.dicon    // SeasarのスマートデプロイのCreatorを定義した dicon
 |  |-dbflute.dicon    // DBFluteの dicon (自動生成)
 |  |-env_ut.txt       // SeasarのUnitTest時の環境タイプ
 |  |-env.txt          // Seasarのアプリ実行時の環境タイプ (ローカル環境用なのでut)
 |  |-jdbc.dicon       // DB接続dicon (URLなどはConfigから取得するようにしている)
 |  |-maihama_config.properties // Maihamaプロジェクト共通のコンフィグ
 |  |-maihama_env.properties    // Maihamaプロジェクト共通の環境依存コンフィグ
 |  |-maihama_message_ja.properties // Maihamaプロジェクト共通の日本語リソース
 |  |-maihama_message.properties    // Maihamaプロジェクト共通の英語リソース
 |  |-projectfw.dicon   // Maihamaプロジェクトフレームワークのコンポーネント定義dicon
 |  |-s2container.dicon // Seasarの大事なdicon (S2ClassBuilder定義含む)
 |
 |-src/allpackage/resources // mavenでpackageするときの共通リソース
 |  |-env.txt // Seasarのアプリ実行時の環境タイプ (product)
 |
 |-src/integration/resources // 結合環境のリソース
 |  |-maihama_env.properties // 結合環境の環境依存コンフィグ
 |    // ※ここにdiconを置くようなことは、原則しないこと
 |
 |-src/production/resources  // 本番環境のリソース
 |  |-maihama_env.properties // 本番環境の環境依存コンフィグ
 |    // ※ここにdiconを置くようなことは、原則しないこと
 |
 |-...

maihama-dockside       // ドメインプロジェクト (Webアプリ)
 |-src/main/java       // Docksideドメインのクラス
 |  |-org.dbflute.maihama
 |     |-app           // ルートパッケージ (Actionクラスなど)
 |     |  |-logic // 画面間で再利用するLogicを配置するパッケージ
 |     |  |-web   // Web関連のクラスを配置するパッケージ (Actionクラスなど)
 |     |     |-base   // Actionなどのスーパークラスを配置するパッケージ
 |     |     |  |-DocksideBaseAction.java // 全てのActionが継承するスーパークラス
 |     |     |  |-...
 |     |     |-login  // ログイン画面 (Action, Form, WebBeanなど)
 |     |     |-member // 会員管理の画面 (Action, Form, WebBeanなど)
 |     |     |  |-MemberListAction.java // 会員一覧画面のAction
 |     |     |  |-MemberListForm.java   // 会員一覧画面のForm
 |     |     |  |-MemberWebBean.java    // 会員ひとりを表す画面表示用Bean
 |     |     |  |-...
 |     |     |-...
 |     |-domainfw       // Docksideドメインのフレームワークパッケージ
 |        |-action      // Action関連の自動生成クラスや継承クラス、アノテーションなど
 |        |-direction   // SAFluteをMaihamaプロジェクト風にするところ☆
 |           |-DocksideConfig.java // dockside_config 対応クラス(自動生成)
 |           |-DocksideFwAssistantDirector.java // SAFluteの現場フィットを司る
 |             // ☆継承してちょっと微調整オーバーライドしているだけで意外にスリム
 |             // (saflute_assist++.diconで定義される)
 |-src/main/resources  // app.dicon, saflute_assist++.dicon など
 |  |-aop++.dicon // アプリ独自のInterceptorを定義するdicon (あまり使わない)
 |  |-app.dicon   // アプリが読み込む最初のdicon
 |  |-customizer.dicon // SeasarのスマートデプロイコンポーネントのAOPなどの設定dicon
 |  |-dockside_config.properties // Docksideドメインのコンフィグ
 |  |-dockside_message_ja.properties // Docksideドメインの日本語リソース
 |  |-dockside_message.properties    // Docksideドメインの英語リソース
 |  |-log4j.properties       // Log4jの設定 (ローカル環境用なのでDEBUG)
 |  |-saflute_assist++.dicon // Config や AssistantDirector を追加するdicon
 |-...

アーキテクチャ概念マップ

アーキテクチャ概念マップを見ながら見るとよいでしょう。

図 : SAFluteアーキテクチャ概念マップ SAFluteアーキテクチャ概念マップ

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

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

おおまかな特徴

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

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

現場フィットを一元管理

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

スマートデプロイ対象を明確に

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

ごちゃませにするとHotDeployトラブルがおきやすく、たとえ convention.dicon で Ignore 設定したとしても、ディベロッパーが気付かずに参照方向を間違える可能性があるため、最初から分けていた方が世話ないという思想です。 (ディベロッパーは、appの外からappの中のクラスを参照してはいけないと覚えるだけ)

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

maihama-dockside
/src/main/java
 |
 |-org.dbflute.maihama
 |  |-app       // ルートパッケージ (スマートデプロイ対象、Actionクラスなど)
 |  |  |-...
 |  |-domainfw  // Docksideドメインのフレームワークパッケージ
 |  |  |-...

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

羽ばたく拡張クラス

SAStrutsやSeasarなどを拡張したクラスは、様々な設定ファイルで定義されます。

struts-config.xml
ActionRequestProcessor, ActionMultipartRequestHandler, PropertiesMessageResourcesFactory
web.xml
RequestLoggingFilter, RequestRoutingFilter, ContainerManagementServlet
jta+UserTransaction.dicon
HookedUserTransaction
creator.dicon
RomanticLogicCreator
customizer.dicon
ConcreteDrivenCustomizerChain, ActionCustomizerChain, ActionTxAttributeCustomizer, RomanticActionCustomizer, ExplicitTxAttributeCustomizer