[Seasar-user:1048] AopProxy とメソッド修飾子について

Sadanori ITO sito_dev
2004年 10月 1日 (金) 04:47:10 JST


伊藤と申します。

現在,開発中の製品に S2 を利用する方向で進めていまして,その中で
気になった点をご質問させていただきます。

MLを拝見している限り,あまり問題になっているようでもないので,
皆さん当然のこととして理解された上で使われているのかも知れませんが,
現状の S2AOP では例えば final が指定されているメソッドには
「アスペクトを登録しても,実際には適用されない」
という認識で間違いないでしょうか?

※まだ S2 初心者なので「こうすれば使えるよ」ということであれば
  ご指摘ください。

以下,当面 final では利用不可という前提で書いてしまいますのでご容赦を。

-----

後述のようなコードを実行すると

BEGIN examples.aop.FooImpl#getMessage()
END examples.aop.FooImpl#getMessage() : Hello

のみ出力されるという意味ですが,これは CGLIB の制限によるものである
とすると,今後 java.lang.reflect.Proxy (?) 等を併用してこの辺りの
制限を緩和する予定はありますでしょうか?

もし,当面予定されていないということであれば,

・該当するメソッド名が存在したため MethodInterceptor は生成されたが,
  実際には final または static 修飾子が指定されていて,アスペクト
  が適用されない場合に警告を出力する
  (オーバーロードされている場合は一つでも適用可であれば警告しない)

という機能を org.seasar.framework.aop.proxy.AopProxy に追加する
パッチを作成してみましたので,ご検討いただければと思います。
オリジナルソースは Seasar2 : バージョン 2.0.20 のものです。

----- 警告出力サンプルはこんな感じです。
WARN  2004-10-01 03:12:37,157 [main] class examples.aop.FooImplの
メソッド(getFinalMessage)にはアスペクトを適用できない修飾子が指定
されています
-----

実際,不勉強にもこの点を認識できていなかったため,*.dicon ファイルの
書き方が間違えているのか?とかいろいろ悩んでしまいました。

※ S2AOP のドキュメントにもこの辺りの記述はないように見えます。

テストコードも書こうと思ったのですが,警告が出力されたかどうかを
判定する方法を思いつきませんでした...

どの程度需要があるのか不明ですが,final 好きの開発者の方には
うっかりミスで悩まずに済むので嬉しい機能ではないかと思います。

ちなみに final なクラスの場合は CGLIB の例外がそのまま出力されるのも
気になると言えば気になるのですが,メソッドの場合に無視されてしまう
のと比べて些細なことかと思い何も対応していません。

以上です。
ご検討の程よろしくお願い致します。長文失礼しました。

---------- 以下,確認に使用したコードです。
----- Foo.java
package examples.aop;

public interface Foo
{
  String getMessage();
  String getFinalMessage();
}

----- FooImpl.java
package examples.aop;

public class FooImpl implements Foo
{
  public String getMessage() {
    return "Hello";
  }

  public final String getFinalMessage() {
    return "Final";
  }
  
  public static String getStaticMessage() {
    return "Static";
  }
}

----- FooProxy.java
package examples.aop;

import org.seasar.framework.aop.Aspect;
import org.seasar.framework.aop.Pointcut;
import org.seasar.framework.aop.interceptors.TraceInterceptor;
import org.seasar.framework.aop.impl.AspectImpl;
import org.seasar.framework.aop.impl.PointcutImpl;
import org.seasar.framework.aop.proxy.AopProxy;

public class FooProxy {

  public static void main(String[] args) {
    Pointcut pointcut = new PointcutImpl(new String[]{".*Message"});
    Aspect aspect = new AspectImpl(new TraceInterceptor(), pointcut);
    AopProxy aopProxy = new AopProxy(FooImpl.class, new Aspect[]{aspect});
    Foo proxy = (Foo) aopProxy.create();
    proxy.getMessage();
    proxy.getFinalMessage();
    ((FooImpl) proxy).getStaticMessage();
  }
}

-- 
s.ito
-------------- next part --------------
テキスト形式以外の添付ファイルを除去しました...
ファイル名: AopProxy-WARN.patch
型:         application/octet-stream
サイズ:     2198 バイト
説明:       無し
URL:        http://lists.sourceforge.jp/mailman/archives/seasar-user/attachments/20041001/ca636460/AopProxy-WARN.obj
-------------- next part --------------
テキスト形式以外の添付ファイルを除去しました...
ファイル名: AopProxy-WARN-SSRMessages_ja.patch
型:         application/octet-stream
サイズ:     913 バイト
説明:       無し
URL:        http://lists.sourceforge.jp/mailman/archives/seasar-user/attachments/20041001/ca636460/AopProxy-WARN-SSRMessages_ja.obj


Seasar-user メーリングリストの案内