まず試してみたのはS2Strutsクイックスタート。S2StrutsとMayaaを使用したチュートリアル。
DBを使わないのでS2Daoは登場しません。なのでとりあえずS2Daoはおいておきます。
なお、Eclipseには以下のプラグインを入れておいたほうがよいです。
- Kijimura・・・diconファイルの編集が便利になる
- matatabi・・・mayaaファイルの編集が便利になる
プラグインを入れる手順(Eclipse3.3+pleiadesを前提)は、
- [ヘルプ]-[ソフトウェア更新]-[検索およびインストール]
- [インストールする新規フィーチャーを検索]-[次へ]
- [新規リモート・サイト]
- 名前:Seasar-3.2とか適当に/URL:http://eclipse.seasar.org/updates/3.2/ を入力して[OK]
- 追加したサイトをチェックして、[終了]
- インストールするプラグインをチェックして[次へ]
- あとは適当に
ちなみに、4で3.2を3.3にすると、matatabiの新しいバージョンが出てきます。
クイックスタートの補足
クイックスタートのとおりにやれば当然動くんですが、Strutsでは様々な設定が必要なところをS2では何もしなくても自動的にやってくれるため、何がどういう仕組みで動いているのかなかなか理解できず。
クイックスタートだけに解説があまり詳しくないので、最低限これだけ理解できれば追えるであろう補足というかメモを書いておく。
とりあえずは全体像をテキトーに描いてみると、

※インタフェースと実装クラスの関係は表現していない
画面→Actionへの値の受け渡し画面の値は、リクエストパス+Dto(またはForm)という名前のクラスに自動的セットされる。
で、リクエストパス+Actionクラスが呼ばれ、ActionクラスのsetXxxDto(またはForm)メソッドで受け取る。
ちなみにDtoだかFormだかの規約はstruts-config.xmlのAutoStrutsConfigRegisterPluginのプロパティformClassPatternで設定可能(単にデフォルトが「(.*Form$)|(.*Dto$)」となっているだけの話)。
Actionも同様にactionClassPatternプロパティで設定可能(デフォルトが「.*Action$」)。
Action→画面への値の受け渡し例えばActionクラスにgetAbcDe()を作成すると、その戻り値がsetAttribute()される。
キーはabcDe(getを除いて先頭Aを小文字にした文字列)となる。
画面ではセットされた値をgetAttribute()すればよいが、そこもmayaaファイルでabcDeとキーを書けば自動的にgetできる。
ビジネスロジックの注入上図の点線のところで、GreetingServiceがActionクラスに注入されています。
これはActionクラスにsetGreetingServiceメソッドを書くと勝手にセットされます。
(細かい調整は可能だが)とにかく型がインタフェースであれば、自動的にこのようなバインディングが行われる。
全てPOJOで書けるDtoにしろActionクラスにしろActionFormやらActionやらをextendsしていません。
規約に従った名前にする、インタフェースと実装を分ける、アクションメソッドの戻り値はStringでforward名を返す、といったルールに従えばPOJOで書け、テストしやすくなる。
DIしてみる
クイックスタートにはなかったが、せっかくなので、簡単なインジェクションをやってみます。
GreetingActionImplクラスに外からメッセージを注入し、Greeting結果にくっつける、というインジェクションをメソッドインジェクションでやってみます。
インジェクションの種類は
こちらに載っています。
GreetingActionImplクラスにmessageフィールドとその注入メソッドを追加します。
また、getGreetingメソッドをメッセージをくっつけるように改造します。
[GreetingActionImpl.java]
public di.Message message;
public void diMessage(di.Message message) {
this.message = message;
}
public String getGreeting() {
return message.getMessage() + " | " + greeting;
}
diパッケージをつくり、以下のインタフェースと実装クラスをつくります。
[Message.java]
package di;
public interface Message {
public String getMessage();
}[MessageImpl.java]
package di;
public class MessageImpl implements Message {
private String message = "はじめてのDI";
@Override
public String getMessage() {
return message;
}
}greeting.diconにインジェクションするための記述を追加します。
メソッドインジェクションなので、initMethod要素とargで引数を指定します。
[greeting.dicon]
<component name="message" class="di.MessageImpl" />
<component class="examples.action.impl.GreetingActionImpl">
<initMethod name="diMessage">
<arg>message</arg>
</initMethod>
</component>このままだと、コンポーネントが二重登録され、TooManyRegistrationRuntimeExceptionがでてしまうので、FileSystemComponentAutoRegisterのところではaddIgnoreClassPatternを追加して登録をしないようにします。
<component class="org.seasar.framework.container.autoregister
.FileSystemComponentAutoRegister">
・
・
・
<initMethod name="addIgnoreClassPattern">
<arg>"examples.action.impl"</arg>
<arg>"GreetingActionImpl"</arg>
</initMethod>
</component>実行結果
“Good evening”の前に“はじめてのDI”がくっつきました。