FAQ

S2AOP

複数のアスペクトを自動登録したい

S2サポーター? (2006-04-29 (土) 19:34:12)

Question
over 2.3のAspectAutoRegisterを使って、自動登録へ切り替えようかと画策しております。

ソースを拝見させていただきましたが、複数のアスペクトを自動登録することはできないのでしょうか?

従来の記述で言えば、

<component ...>
  <aspect>aop.traseInterceptor</aspect>
  <aspect>dao.interceptor</aspect>
</component>

のような場合です。


Answer
InterceptorChain を使うのがよいかと思います.

<component name="traceAndDao" class="org.seasar.framework.aop.interceptors.InterceptorChain">
    <initMethod name="add">aop.traceInterceptor</initMethod>
    <initMethod name="add">dop.interceptor</initMethod>
</component>


としておいて,traceAndDao を AspectAutoRegister で設定.

参考投稿
http://ml.seasar.org/archives/seasar-user/2005-October/000618.html
http://ml.seasar.org/archives/seasar-user/2005-October/000619.html

diconでOGNL式にaspect適用可能か?

S2サポーター? (2006-04-29 (土) 16:32:41)

Question
diconファイルで、OGNL式で取得したコンポーネントに対して
アスペクトを適用するように記述することは可能でしょうか?

 以下のように書きたかったのですが、エラーになります。

<component>
    @hogeFactory @ HOGE
    <aspect>hogeInterceptor</aspect>
</component>


Answer
できません.

S2AOP は,元のクラスを継承したサブクラスを作成します.
アスペクトが適用されるのはそのサブクラスのインスタンスに
なります.
OGNL で取得したコンポーネントはすでにインスタンス化されて
しまっており,S2AOP が作成したサブクラスのインスタンスでは
ないためアスペクトは適用されません.

DelegateInterceptor を使えばやりたいことが
できるかもしれません.

<component class="...">
  <aspect>hogeInterceptor</aspect>
  <aspect>
    <component class="org.seasar.framework.aop.interceptors.DelegateInterceptor">
      <property name="target">@hogeFactory @ HOGE</property>
    </component>
  </aspect>
</component>


一番外側の <component> 要素には class 属性を指定する必要があります.
インタフェースを指定しても構いません.このコンポーネントを取得してメソッドを呼び出すと,
最初に hogeInterceptor が適用され,その後にDelegateInterceptor が適用されます.

DelegateInterceptor は target プロパティに指定されたコンポーネントに委譲します (同じメソッドを呼び出します).
当然ですが,コンテナから取得したコンポーネントのメソッドを呼び出さないとアスペクトは適用されません.
hogeFactory.HOGE のメソッドを呼び出してもダメです.

参考投稿
http://ml.seasar.org/archives/seasar-user/2006-April/005405.html
http://ml.seasar.org/archives/seasar-user/2006-April/005408.html

アスペクト (インターセプタ) を singleton 以外にすることはできますか?


Question
aspect (インターセプタ) のインスタンスモードを singleton 以外にすることはできますか?
インスタンスモードを request にして HttpServletRequest のプロパティを用意しましたが設定されません.

<component name="myInterceptor" instance="request" class="..."/>

<component name="myComponent" class="...">
    <aspect>myInterceptor</aspect>
</component>


Answer

Seasar 2.3.7 以前

インターセプタに InterceptorLifecycleAdapter を適用してください

S2AOP は,元のクラスを継承したサブクラスを作成する際にインターセプタをコンテナから取得します.
このため,インターセプタのインスタンスモードが prototype や request であっても,コンテナの初期化時にインスタンス化されてしまい,HttpRequest や HttpSession を受け取ることができません.

このような場合には,インターセプタの instance 属性を prototype にした上で, InterceptorLifecycleAdapter を適用してください.
※この方法はインターセプタが org.seasar.framework.aop.interceptors.AbstractInterceptor を継承している場合のみ有効です.

<include path="aop.dicon"/>

<component name="myInterceptor" instance="prototype" class="...">
    <aspect>aop.lifecycleAdapter</aspect>
</component>

<component name="myComponent" instance="request" class="...">
    <aspect>myInterceptor</aspect>
</component>


これにより,myInterceptor の invoke メソッドが呼ばれるたびに InterceptorLifecycleAdapter が myInterceptor をコンテナから取得して委譲します.

Client -> myInterceptor (コンテナ初期化時に取得) -> InterceptorLifecycleAdapter -> myInterceptor (毎回取得) -> myComponent

という呼び出しシーケンスになります.最初の myInterceptor と 後の myInterceptor は別のインスタンスになります (myInterceptor が singleton 以外の場合).

参考投稿
http://ml.seasar.org/archives/seasar-user/2005-December/000242.html
http://ml.seasar.org/archives/seasar-user/2005-December/000250.html

この方法は Seasar 2.3.8 以降では利用できません.

Seasar 2.3.13 以降

対象のコンポーネントには InterceptorAdapter をアスペクトとして適用してください.
本来のインターセプタはインスタンスモードを prototype にして,その名前を InterceptorAdapter の add(String) メソッドで登録します.

<component name="myInterceptor" instance="prototype" class="..."/>

<component class="...">
  <aspect>
    <component class="org.seasar.framework.aop.interceptors.InterceptorAdapter">
      <initMethod name="add"><arg>"myInterceptor"</arg></initMethod>
    </component>
  </aspect>
</component>

これにより,InterceptorAdaptor の invoke メソッドが呼ばれるたびに InterceptorAdapter が myInterceptor をコンテナから取得して委譲します.

Client -> InterceptorAdaptor (コンテナ初期化時に取得) -> myInterceptor (毎回取得) -> myComponent

という呼び出しシーケンスになります.

参考投稿
http://ml.seasar.org/archives/seasar-user/2006-September/006515.html
http://ml.seasar.org/archives/seasar-user/2006-September/006523.html

この方法はSeasar2.3.12 以前では利用できません.

Seasar2.4.10 以降で SMART deploy を使う場合

インターセプタを適用する AspectCustomizer の useLookupAdapter プロパティを true に設定してください.

<component class="org.seasar.framework.container.customizer.AspectCustomizer">
  <property name="interceptorName">"requestInterceptor"</property>
  <property name="useLookupAdapter">true</property>
</component>

CustomizerChain#addAspectCustomizer を使っていて,ポイントカットを指定していない場合は第 2 引数に true を設定してください.

<initMethod name="addAspectCustomizer">
  <arg>"requestInterceptor"</arg><!-- interceptorName -->
  <arg>true</arg><!-- useLookupAdapter -->
</initMethod>

ポイントカットを指定している場合は第 3 引数に true を設定してください.

<initMethod name="addAspectCustomizer">
  <arg>"requestInterceptor"</arg><!-- interceptorName -->
  <arg>"do.*"</arg><!-- pointcut -->
  <arg>true</arg><!-- useLookupAdapter -->
</initMethod>

この方法はSeasar2.4.9 以前では利用できません.


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2009-05-14 (木) 17:51:46 (2873d)