Seasar2再学習めも
久しぶりに時間が取れたので,
Seasar 2 徹底入門 SAStruts/S2JDBC 対応
- 作者: 竹添直樹
- 出版社/メーカー: 翔泳社
- 発売日: 2010/04/20
- メディア: 大型本
- 購入: 10人 クリック: 270回
- この商品を含むブログ (33件) を見る
S2Containerの初期化
- SingletonS2ContainerFactory#init()
- app.diconの内容でコンテナを初期化する
コンポーネントの取得
- S2Container#getComponent()で取得
- できるだけ型を指定して取得するほうが吉
DIの設定
ライフサイクルの選び方
singleton,application,sessionなどライフサイクルが長い場合はスレッドセーフであることを十分に留意する必要がある。request,session,applicationはWebアプリケーション環境下のみで指定可能。利用する場合はweb.xmlにてS2ContainerFilterの設定が必要。
初期化と破棄のタイミング
DIできないライフサイクル
outerコンポーネントの使い方
インジェクションの種類
自動バインディング
autoBinding属性 | 内容 |
---|---|
auto | コンストラクタとプロパティに対して自動バインディングを行う。autoBinding属性を省略した場合はauto |
semiauto | アノテーションなどで明示的に指定したプロパティに対して自動バインディングを行う |
constructor | コンストラクタに対して自動バインディングを行う |
property | プロパティに対して自動バインディングを行う |
none | 自動バインディングを行わない |
- 自動バインディングが有効でも,diconファイルで明示的にインジェクションの設定が行われている場合は,そちらが有効
プロパティへの自動バインディング
外部バインディング
Webアプリケーションにおいて,リクエストパラメータの値などを自動的にコンポーネントにセットするために使用される。componentタグのexternalBinding属性をtrueに設定することで利用できる。コンポーネントにはリクエストパラメータ名と同じ名前でプロパティを作成しておくと,S2Containerによって自動的にリクエストパラメータが設定される。
Seasar2が提供するインターセプター
Seasar2にはデフォルトでいくつかのインターセプターが用意されている。これらのインターセプターの中にはaop.diconであらかじめ定義されているものもあり,aop.diconをインクルードしていればaspectタグでインターセプターのコンポーネント名を指定するだけで利用することができる。
SMART deploy対象のコンポーネントの場合,アノテーションによってインターセプターを適用することも可能。@Traceアノテーションをメソッドに記述すると,diconファイルで設定を行わなくてもTraceInterceptorが適用される。
クラス名 | コンポーネント名 | 説明 | アノテーション定義 |
---|---|---|---|
TraceInterceptor | aop.traceInterceptor | トレースログを出力する | @Trace |
ClassLoaderAwareTraceInterceptor | aop.classLoaderAwareTraceInterceptor | クラスローダの情報も出力するTraceInterceptor | - |
SimpleTraceInterceptor | aop.simpleTraceInterceptor | シンプルなトレースログを出力する | @SimpleTrace |
SyncInterceptor | aop.syncInterceptor | メソッドを同期化する | @Sync |
TraceThrowsInterceptor | aop.traceThrowsInterceptor | 例外のトレースログを出力する | @TraceThrows |
ToStringInterceptor | aop.toStringInterceptor | フィールドの情報をtoString()で出力する | @ToString |
RemoveSessionInterceptor | aop.removeSessionInterceptor | メソッド終了時にセッションに格納されているオブジェクトを削除する | @RemoveSession |
InvalidateSessionInterceptor | aop.invalidateSessionInterceptor | メソッド終了時にセッションを破棄する | @InvalidateSession |
DependencyLookupInterceptor | aop.dependencyLookupInterceptor | S2Containerから取得したコンポーネントを返却する | @DependencyLookup |
InterceptorLifecycleAdapter | aop.lifecycleAdapter | ライフサイクルがsingleton以外のインターセプターを使うためのアダプタ*1 | - |
DelegateInterceptor | diconファイルには未登録 | メソッド呼び出しを他のメソッドに委譲する*2 | - |
インターセプターのグループ化
InterceptorChainを使って複数のインターセプターをグループ化できる。
独自インターセプターの作成
- org.aopalliance.intercept.MethodInterceptorインタフェースを継承
- AOPアライアンス標準のインタフェース
- org.seasar.framework.aop.interceptors.AbstractInterceptorを継承
- Seasar2に特化したいくつかのメソッドが実装されている
上記2つの方法で実装する。
独自のインターセプターをアノテーションで適用できるようにする
- @interceptorというメタアノテーションを付与
- 「アノテーションの単純クラス名の最初の1文字を小文字にした文字列+Interceptor」というコンポーネント名でアノテーションが登録されていること
上記のルールでインターセプターを適用するためのアノテーションが利用できる。
インタータイプ
インタータイプによって,クラスの静的な構造を変更(クラスにフィールドやメソッドを追加)することができる。
InterTypeChain
複数のインタータイプをグループ化し,再利用しやすくする。
AOPによるトランザクション制御
Seasar2ではトランザクションの制御を行うためのインターセプターが用意されており,j2ee.diconで定義されている。
クラス名 | コンポーネント名 | 説明 |
---|---|---|
RequiredInterceptor | j2ee.requiredTx | トランザクションが開始されていなければ,自動的にトランザクションを開始する。すでにトランザクションが開始されていれば,そのトランザクションを引き継ぐ。 |
RequiresNewInterceptor | j2ee.requiresNewTx | 常に新しいトランザクションを開始させる。既存のトランザクションが開始されているなら,既存のトランザクションを中断し,自分自身のトランザクションの終了後,中断したトランザクションを復帰させる |
MandatoryInterceptor | j2ee.mandatoryTx | トランザクションがすでに開始されていなければエラーにする |
NotSupportedInterceptor | j2ee.notSupportedTx | 既存のトランザクションが開始されているなら,既存のトランザクションを中断する。コンポーネントのメソッドの終了後,中断したトランザクションを復帰させる |
NeverInterceptor | j2ee.neverTx | トランザクション制御を行わない。トランザクションが開始されていた場合はエラーにする |
インターセプターが適用されたメソッド内で例外が発生した場合,基本的にトランザクションはロールバックされる。ただし,例外はスローしたいがトランザクションはコミットしたいケースは,インターセプターにaddCommitRule()メソッドで例外の型を登録しておくと,特定の例外が発生した場合にコミットすることができる。
Seasar2のSMART deploy機能を使用する場合はこれらのインターセプターを個別に適用するのではなく,カスタマイザという仕組みを使ってアクションクラスに一括してトランザクション制御のためのインターセプターを適用する。*3
AopProxy
org.seasar.framework.aop.proxy.AopProxyを使うと,S2Containerを使わずにJavaコードで任意のオブジェクトに対してAOPを適用することができる。
コンポーネントの自動登録
S2Containerには特定の命名規則に従って作成されたクラスを自動的にコンポーネントとして登録するためのComponentAutoRegisterというクラスが用意されており,diconファイルに登録しておくことで,コンポーネントの自動登録を行うことができる。
ComponentAutoRegisterにはいくつかの種類がある。
アスペクトの自動登録
AspectAutoRegisterを使用すると,アスペクトの登録も自動化できる。アスペクトの自動登録をコンポーネントの自動登録と組み合わせて使用する場合,ComponentAutoRegisterの定義よりも後にAspectAutoRegisterの定義を記述する必要がある点に注意。
AspectAutoRegisterの実装には,以下の2種類がある。
- AspectAutoRegister
- クラス名のパターンを指定してアスペクトを自動登録
- InterfaceAspectAutoRegister
- 指定したインタフェースを実装したクラスに対してアスペクトを自動登録
アノテーション
Seasar2では,DIの設定は基本的にdiconファイルで行うが,アノテーションを使ってDIやAOPの設定を行うことができる。
アノテーション | 説明 |
---|---|
@Component | S2Containerで管理するクラスに付与する。diconファイルのcomponentタグに相当 |
@Binding | DIするプロパティに付与する。diconファイルのpropertyタグに相当 |
@Aspect | AOPを適用するクラスまたはメソッドに付与する。diconファイルのaspectタグに相当 |
@InterType | InterTypeに適用するクラスに付与する。diconファイルのInterTypeタグに相当 |
@initMethod | コンポーネントの初期化用メソッドに付与する。diconファイルのinitMethodタグに相当 |
@DestroyMethod | コンポーネントの廃棄用メソッドに付与する。diconファイルのdestroyMethodタグに相当 |
@Bindingアノテーションと同等の機能を提供するアノテーションとして,@Resourceアノテーションも存在する。@ResourceアノテーションはJavaEE標準のアノテーションであるため,通常は@Resourceアノテーションを利用することが推奨されている。ただし,@ResourceアノテーションはDIするコンポーネントが見つからない場合にエラーとなってしまう。コンポーネントが存在する場合のみDIするには,@Resourceアノテーションの代わりに,bindingType属性にBindingType.MAYを指定した@Bindingアノテーションを使用するとよい。
Webアプリケーションでの利用
S2ContainerをWebアプリケーションで利用する場合,web.xmlでの設定が必要。
- S2ContainerServletの登録
- Webアプリケーションのコンテキスト起動時にS2Containerの初期化を行う。
- S2ContainerFilterの登録
- コンポーネントのライフサイクル(application,session,request)を使用するために登録。
- HotdeployFilterの登録
- S2ContainerFilterよりも前に適用されるように設定する必要がある。
- S2ContainerFilterよりも上にHotdeployFilterを記述する。
- S2ContainerFilterよりも前に適用されるように設定する必要がある。
- 文字化け対策
暗黙コンポーネント
以下のコンポーネントについては,diconファイルで特に設定を行わなくても利用することができる。
型 | コンポーネント名 | 備考 |
---|---|---|
S2Container | container | コンテナ |
HttpServletRequest | request | リクエスト |
HttpServletResponse | response | レスポンス |
ServletContext | application | サーブレットコンテキスト |
Map | applicationScope | ServletContextの属性 |
Map | initParam | ServletContextの初期化パラメータ |
Map | sessionScope | HttpSessionの属性 |
Map | requestScope | HttpServletRequestの属性 |
Map | cookie | クッキー |
Map | header | リクエストヘッダ(値はString) |
Map | headerValues | リクエストヘッダ(値はString[]) |
Map | params | HttpServletRequestのパラメータ(値はString) |
Map | paramValues | HttpServletRequestのパラメータ(値はString[]) |
以下のようにフィールドを定義しておくと,S2ContainerによってHttpServletRequestやHttpServletResponseがDIされる。
public class HelloAction { @Resource protected HttpServletRequest request; @Resource protected HttpServletResponse response; }