質問
AspectJを使用して、選択したクラスの引数を持つすべてのパブリックメソッドをアドバイスしています。私は次を試しました:
pointcut permissionCheckMethods(Session sess) :
(execution(public * *(.., Session)) && args(*, sess));
これは、少なくとも2つの引数を持つメソッドに対して素晴らしく機能しています:
public void delete(Object item, Session currentSession);
ただし、次のようなメソッドでは機能しません。
public List listAll(Session currentSession);
ポイントカットを変更して、両方のメソッドの実行をアドバイスするにはどうすればよいですか?つまり、「..」が期待されていました。 「ゼロ以上の引数」を表すワイルドカードですが、代わりに「1つ以上」を意味するように見えます...
解決
まあ...私はこの厄介なトリックでそれを回避しました。誰かが「公式」と表示されるのをまだ待っています。ポイントカット定義。
pointcut permissionCheckMethods(EhealthSession eheSess) :
(execution(public * *(.., EhealthSession)) && args(*, eheSess))
&& !within(it.___.security.PermissionsCheck);
pointcut permissionCheckMethods2(EhealthSession eheSess) :
(execution(public * *(EhealthSession)) && args(eheSess))
&& !within(it.___.security.PermissionsCheck)
&& !within(it.___.app.impl.EhealthApplicationImpl);
before(EhealthSession eheSess) throws AuthorizationException : permissionCheckMethods(eheSess)
{
Signature sig = thisJoinPointStaticPart.getSignature();
check(eheSess, sig);
}
before(EhealthSession eheSess) throws AuthorizationException : permissionCheckMethods2(eheSess)
{
Signature sig = thisJoinPointStaticPart.getSignature();
check(eheSess, sig);
}
他のヒント
方法:
pointcut permissionCheckMethods(Session sess) :
(execution(public * *(..)) && args(.., sess));
最後の(または唯一の)引数がSession型の場合、これは一致すると思います。 argsの位置を交換することにより、first-or-onlyに一致させることもできます。しかし、任意の位置に一致することが可能かどうかはわかりません。
AspectJ構文を拡張することはできませんが、回避策を提供できます。しかし、最初に、ポイントカットで args
定義を使用して必要なことを実行できない理由を説明しましょう:メソッドシグネチャ内のどこかに EhealthSession
パラメータと一致する場合、AspectJは署名にそのクラスの複数のパラメーターが含まれる場合をどのように処理する必要がありますか? eheSess
の意味はあいまいです。
今すぐ回避策:遅くなる可能性があります-環境にどれだけ依存するかをテストするだけです-しかし、パラメータリストに関係なく、すべての潜在的なメソッドにポイントカットを一致させてから、アドバイスで必要なパラメータを見つけることができますパラメータリストの検査:
pointcut permissionCheckMethods() : execution(public * *(..));
before() throws AuthorizationException : permissionCheckMethods() {
for (Object arg : thisJoinPoint.getArgs()) {
if (arg instanceof EhealthSession)
check(arg, thisJoinPointStaticPart.getSignature());
}
}
PS: within(SomeBaseClass +)
または within(* Postfix)
または within(com.company.package .. * )
ユニバース全体にアドバイスを適用しないようにします。
次のように、末尾と先頭に..(二重点)を使用する必要があります。
pointcut permissionCheckMethods(Session sess) :
(execution(public * *(.., Session , ..)) );
また、&&を取り除くargs(*、sess)
は、最初のparamにはどんなタイプでも、2番目のparamには sess
で、2つ以下のparamsのメソッドだけをキャッチすることを意味するためです。