[[FAQ]]

*S2AOP [#db17a433]

#contents

**複数のアスペクトを自動登録したい [#vb7922e6]
>[[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適用可能か? [#d29c919e]
>[[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 以外にすることはできますか? [#z685b23f]
~
''Question''~
aspect (インターセプタ) のインスタンスモードを singleton 以外にすることはできますか?~
インスタンスモードを request にして HttpServletRequest のプロパティを用意しましたが設定されません.
~
~
 <component name="myInterceptor" instance="request" class="..."/>
 
 <component name="myComponent" class="...">
     <aspect>myInterceptor</aspect>
 </component>
~
''Answer''~
*** [[Seasar]] 2.3.7 以前 [#qa5595ff]
インターセプタに [[InterceptorLifecycleAdapter:http://s2container.seasar.org/ja/aop.html#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 以降 [#i45fc6c8]
対象のコンポーネントには 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~

この方法は[[Seasar]]2.3.12 以前では利用できません.

*** [[Seasar]]2.4.10 以降で SMART deploy を使う場合 [#q69751d4]
インターセプタを適用する AspectCustomizer の useLookupAdapter プロパティを true に設定してください.

 <component class="org.seasar.framework.container.customizer.AspectCustomizer">
   <property name="interceptorName">"requestInterceptor"</property>
   <property name="useLookupAdapter">true</property>
   <property name="interceptorName">"requestInterceptor"</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>


この方法は[[Seasar]]2.4.9 以前では利用できません.

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS