Spring Boot AOPで、メソッド「Around」期間中にクラスアノテーションを取得するにはどうすればよいですか?
ここにいるすべての友達に感謝します。に設定されたアノテーションのアノテーションパラメータを取得する方法を知っていますmethod
。
Class
レベルに注釈を追加したいのですが。Class
AOP Aroundメソッドで属性を取得するにはどうすればよいですか?
私はからの応答値を変更する必要がある理由ところで、私は、別の質問を持っているvoid
にObject
して復帰pjp.proceed()
。メソッドに応答がない場合、リクエストはフリーズします。
HasRoleアノテーションを持つメソッドの場合
@Around("@annotation(com.example.demo.aspect.annotation.HasRole) && @annotation(annotation)")
public void aroundHasRole(ProceedingJoinPoint pjp, HasRole annotation) throws Throwable {
log.info("value->>{}", annotation.value());
pjp.proceed();
}
HasRoleアノテーションを持つクラスまたはメソッドの場合
@Around("(@within(com.example.demo.aspect.annotation.IsAdmin)"
+ "|| @annotation(com.example.demo.aspect.annotation.IsAdmin))")
public Object aroundHasRole(ProceedingJoinPoint pjp) throws Throwable {
<<How to get annotation information here?>>
return pjp.proceed();
}
回答
お気づきかもしれませんが、異なる||
ブランチからの情報をアドバイスメソッドパラメータにバインドすることはできません。あいまいになるためです。こことここの私の回答も参照してください。したがって、醜い(そして遅い)反射を避けたい場合は、他の回答で推奨したことを実行し、2つの異なるアドバイスを記述して、コードの重複を避けることがここで懸念される場合は、共通コードをヘルパーメソッドに分解します。このようなもの(コード構造についてのアイデアを提供するためだけに、テストされていません):
@Around("@within(annotation)")
public Object classIsAdmin(ProceedingJoinPoint pjp, IsAdmin annotation) throws Throwable {
return commonIsAdmin(pjp, annotation);
}
@Around("@annotation(annotation)")
public Object methodIsAdmin(ProceedingJoinPoint pjp, IsAdmin annotation) throws Throwable {
return commonIsAdmin(pjp, annotation);
}
public Object commonIsAdmin(ProceedingJoinPoint pjp, IsAdmin annotation) throws Throwable {
// Here you would place all common advice code.
// Non-common code could remain in the original advice methods.
log.info("value->>{}", annotation.value());
return pjp.proceed();
}
なぜ私はからの応答値を変更する必要があり
void
へObject
と復帰pjp.proceed()
。メソッドに応答がない場合、リクエストはフリーズします。
@Before
または@After
アドバイスとは対照的に、アドバイスでは、@Around
呼び出しを行わないことでターゲットメソッドの実行を完全にスキップするかproceed()
、の結果を破棄または変更することで、戻り値を変更できますproceed()
。返すものは完全に自由です。ターゲットメソッドの戻り値の型と一致する必要があります。
そうは言っても、アラウンドアドバイスメソッドには、インターセプトするターゲットメソッドの戻り値の型と一致する戻り値の型も必要であることが明らかになるはずです。アドバイスが共通のスーパータイプのない多数のタイプを対象としている場合MyType
は、スーパータイプのような正確なタイプ、または単にObject
(すべてのタイプのスーパータイプ)にすることができます。アドバイスは、void
すべてのターゲットメソッドも返す場合(およびその場合のみ)の戻り値の型を持つこともできますvoid
(そうでない場合、ポイントカット自体が一致する場合でも、アドバイスはそれらのメソッドと一致しません)。
したがって、アラウンドアドバイスが一致するかどうかは、ポイントカット自体と戻り値の型の組み合わせによって決定されます。これをツールとして使用して、特定の戻り値の型を定義することにより、ポイントカットの一致を制限できます(これにはproceed()
、proceed()
常にを返すため、の戻り値をキャストする必要がありますObject
)。
ターゲットメソッドのようなプリミティブ型を返す場合ところで、int
、boolean
などを、そしてアドバイスをする結果を自動ラップでしょうInteger
かBoolean
。
ここで見つけることができることをここで説明しているので、SpringAOPとAspectJのマニュアルまたはチュートリアルを読む必要があります。
更新: OPは、パラメーターのバインドに関するドキュメントと、名前の決定方法の説明を求めました。
- あなたが指定することができます
argNames
例えば、すべてのアドバイスのタイプ、のためのパラメータを@Before
、@After
、@Around
。 - そのアノテーションパラメータが存在しない場合、Spring AOPは、コンパイルされている場合、クラスファイルのデバッグ情報を介してアドバイスメソッドのパラメータ名を照合しようとします。そうでない場合、照合は失敗します。
- Spring AOPの代わりにコンパイル時ウィービングで完全なAspectJを使用する場合、AspectJコンパイラーはコンパイル中に必要な情報を判別できるため、名前の判別はデバッグ情報なしでも機能します。
これらはすべて、SpringAOPのマニュアルで説明されています。
リフレクションを介してクラスを取得し、クラスを介して固定メソッド情報を取得し、メソッドのアノテーションを取得します。このように、あなたは反映することができるはずです