17

次の場合、メソッドに一致するポイントカットでアスペクトを作成する必要があります。

  • 公開されている
  • そのクラスには @Controller アノテーションが付けられています (最終的にはありません)
  • そのパラメーターの 1 つ (多数のパラメーターを持つことができます) には、@MyParamAnnotation の注釈が付けられます。

最初の 2 つの条件は簡単だと思いますが、3 つ目の条件を Spring で実現できるかどうかはわかりません。そうでない場合は、次のように変更できます。

  • そのパラメーターの 1 つは、タイプ com.me.MyType のインスタンスです (または何らかのインターフェースを実装します)。

これを達成することは可能だと思いますか? そして、パフォーマンスは良いでしょうか?

ありがとう

EDIT : マッチング方法の一例。ご覧のとおり、MyMethod には注釈が付けられていません (ただし、可能です)。

@Controller
public class MyClass {
    public void MyMethod (String arg0, @MyParamAnnotation Object arg1, Long arg3) {
        ...
    }
}

編集:@Espenの回答に基づいて、私が最終的に使用したソリューション。ご覧のとおり、条件を少し変更しました。クラスは実際には @Controller である必要はありません。

@Around("execution(public * * (.., @SessionInject (*), ..))")
public void methodAround(JoinPoint joinPoint) throws Exception {
    ...
}
4

1 に答える 1

22

面白い問題だったので、ちょっとしたサンプルアプリを作ってみました!(その後、Sinuhe のフィードバックで改善されました。)

DemoControllerアスペクトの例として機能するクラスを作成しました。

@Controller
public class DemoController {

    public void soSomething(String s, @MyParamAnnotation Double d, Integer i) {
    }

    public void doSomething(String s, long l, @MyParamAnnotation int i) {
    }

    public void doSomething(@MyParamAnnotation String s) {
    }

    public void doSomething(long l) {
    }
}

最初の 3 つのメソッドに結合ポイントを追加する側面ですが、パラメーターに注釈が付けられていない最後のメソッドには追加しません@MyParamAnnotation

@Aspect
public class ParameterAspect {

    @Pointcut("within(@org.springframework.stereotype.Controller *)")
    public void beanAnnotatedWithAtController() {
    }

    @Pointcut("execution(public * *(.., @aspects.MyParamAnnotation (*), ..))")
    public void methodWithAnnotationOnAtLeastOneParameter() {
    }

    @Before("beanAnnotatedWithAtController() " 
            + "&& methodWithAnnotationOnAtLeastOneParameter()")
    public void beforeMethod() {    
        System.out.println("At least one of the parameters are " 
                  + "annotated with @MyParamAnnotation");
    }
}

最初のポイントカットは、 でマークされたクラス内のすべてのメソッドにジョインポイントを作成します@Controller

2 番目のポイントカットは、次の条件が満たされたときにジョインポイントを追加します。

  • 公開メソッド
  • first*は、すべての戻り値の型のワイルドカードです。
  • 2 番目*は、すべてのクラスのすべてのメソッドのワイルドカードです。
  • (..,注釈付きパラメーターの前にある任意のタイプのゼロから多数のパラメーターに一致します。
  • @aspects.MyParamAnnotation (*),指定された注釈で注釈が付けられたパラメーターに一致します。
  • ..)注釈付きパラメーターの後の任意のタイプのゼロから多数のパラメーターに一致します。

最後に、@Beforeアドバイスは、両方のポイントカットのすべての条件が満たされるすべてのメソッドをアドバイスします。

ポイントカットは AspectJ と Spring AOP の両方で動作します!

パフォーマンスに関しては。特にコンパイル時またはロード時にウィービングを行う AspectJ では、オーバーヘッドは小さくなります。

于 2010-05-04T16:12:04.243 に答える