読者です 読者をやめる 読者になる 読者になる
無料で使えるシステムトレードフレームワーク「Jiji」 をリリースしました!

・OANDA Trade APIを利用した、オープンソースのシステムトレードフレームワークです。
・自分だけの取引アルゴリズムで、誰でも、いますぐ、かんたんに、自動取引を開始できます。

Guiceのインターセプタってprivateメソッドには適用できないんだっけ?

privateメソッドにインターセプタを適用したはずが、どうもうまく設定できていない風の動作になったのでちょっと調査。ドキュメントのAOPのLimitationsのところに記述があり、適用対象のメソッド(を持つクラス)は以下の条件を満たす必要があるとのことです。

  • クラスが、public or パッケージプライベート(default)であること。
  • クラスが、finalでないこと。
  • メソッドが、public or protected or パッケージプライベート(default)であること。
  • メソッドが、finalでないこと。
  • インスタンスが@Inject-annotatedまたはデフォルトコンストラクタGuiceで作成されていること。

なるほど、アクセス修飾子についてはprivate以外であればOKなのか。ということで検証してみます。

public static void main ( String[] args ) {
    
    // コンテナ
    Service s = Guice.createInjector( new AbstractModule(){
        protected void configure() {
            binder().bind( Service.class );
            // メソッド名を出力するインターセプタを適用
            binder().bindInterceptor(any(), any(), new MethodInterceptor(){
                @Override public Object invoke(MethodInvocation mi) throws Throwable {
                    System.out.println( "intercept:" + mi.getMethod().getName() );
                    return mi.proceed();
                }
            });
        }
    }).getInstance(Service.class);
     s.all();
}

static class Service {
    public void all() {
        publicMethod();
        protectedMethod();
        defaultMethod();
        privateMethod();
    }
    public void publicMethod() {
        System.out.println( "public" );
    }
    protected void protectedMethod() {
        System.out.println( "protected" );
    }
    void defaultMethod() {
        System.out.println( "default" );
    }
    private void privateMethod() {
        System.out.println( "private" );
    }
}

実行結果です。

intercept:all
intercept:publicMethod
public
intercept:protectedMethod
protected
intercept:defaultMethod
default
private

ふむ。