簡體   English   中英

Spring Boot AOP中,在方法“Around”期間如何獲取類注解?

[英]In Spring Boot AOP, how to get class annotation when in the method “Around” period?

感謝這里的所有朋友。 我知道如何獲取method設置的注釋的注釋參數。

雖然我想在Class級別添加注釋。 如何在 AOP Around 方法中從Class中檢索屬性?

順便說一句,我還有一個問題,為什么我需要將響應值從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();

}

您可能已經注意到,您不能綁定來自不同||信息。 分支到建議方法參數,因為它會模棱兩可,另請參閱我的答案herehere 因此,如果您想避免丑陋(和緩慢)的反射,請按照我在其他答案中的建議並編寫兩個不同的建議,如果您在這里擔心避免代碼重復,則將公共代碼分解為輔助方法。 像這樣的東西(未經測試,只是為了讓您了解代碼結構):

@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返回類型(否則通知將不匹配這些方法,即使切入點本身匹配)。

所以如果一個around通知匹配是由切入點本身和返回類型的組合決定的。 您可以將其用作通過定義特定返回類型來限制切入點匹配的工具(然后您需要將proceed()的返回值強制轉換為該類型,因為proceed()總是返回一個Object )。

順便說一句,如果目標方法返回一個原始類型,如intboolean等,那么建議將自動包裝結果為IntegerBoolean

您真的應該閱讀 Spring AOP 和 AspectJ 手冊或教程,因為我在這里解釋了可以在那里找到的內容。


更新: OP 要求提供有關參數綁定的文檔以及如何確定名稱的說明:

  • 您可以指定一個argNames所有意見類型,例如參數@Before@After@Around
  • 如果該注解參數不存在,Spring AOP 將嘗試通過類文件調試信息匹配通知方法參數名稱(如果已編譯)。否則在這種情況下匹配將失敗。
  • 當使用帶有編譯時編織的完整 AspectJ 而不是 Spring AOP 時,確定名稱也可以在沒有調試信息的情況下工作,因為 AspectJ 編譯器可以在編譯期間確定必要的信息。

所有這些都在Spring AOP 手冊中進行了描述。

通過反射獲取類,通過類獲取固定的方法信息,獲取方法上的注解。 這樣,你應該能夠反映

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM