簡體   English   中英

Spring-AOP切入點不起作用?

[英]Spring-AOP pointcut not working?

以下是我的代碼段:

ServiceImpl.java

@Service
public class ServiceImpl implements Service {
  private Response worker(Audit send) throws ArgumentException {
    System.out.println("STEP_1");
    worker(send.getRequest(), send.getId());
  }

  private Response worker(Request request, String id) throws ArgumentException {
    System.out.println("STEP_2");
    try {
      //throwing some exception
    } catch (Exception e) {
      System.out.println("STEP_3");
    }
  }
}

現在,我想要的是每當從方法worker(Request request, String id)拋出NullPointerExceptionworker(Request request, String id)如上所示,我想執行一些特定的任務。 為此,我編寫了一個Aspect類,該類如下:

MyAspect.java

@Aspect
@Component
public class MyAspect{
  @Pointcut("com.xyz.myapp.ServiceImpl.worker() && args(request,..)")
  private void someOperation(Request request) {}

  @Before("someOperation(request)")
  public void process(Request request) {
    System.out.println("SUCCESS");
  }

  @AfterThrowing("com.xyz.myapp.ServiceImpl.worker() && args(request,..)")
  public void doRecoveryActions() {
    System.out.println("EXCEPTION_SUCCESS");
  }
}

電流輸出:

STEP_1 
STEP_2
STEP_3

所需輸出:

STEP_1 
STEP_2
STEP_3
SUCCESS
EXCEPTION_SUCCESS

如您所見, MyAspect.java沒有被觸發,因此不打印值。 這可能是什么原因?

注意:

  1. 我也嘗試過將工人作為公共班級,但沒有用。

  2. 還嘗試更改方法的名稱,以消除任何也不起作用的重載問題。

  3. 到目前為止,嘗試其他各種切入點表達式都是徒勞的。

  4. 在我的應用程序中,還有其他方面的類也可以正常工作。

您犯了一個典型的Spring AOP初學者錯誤:您假定它適用於私有方法,但正如文檔明確指出的那樣,它不是。 Spring AOP基於動態代理,當通過JDK代理實現接口時,它們僅適用於公共方法,而使用CGLIB代理時,僅適用於受保護的和程序包作用域的方法。

如果要從一個方面截獲該方法,則應公開worker()方法。

PS:成熟的AspectJ也適用於私有方法,但是在這里切換到另一個AOP框架將是多余的。


更新:您的代碼中還有其他問題:

  • 第一個worker方法,即使您將其公開,也不會返回任何內容。 最后一條語句應該是return worker(send.getRequest(), send.getId()); ,而不僅僅是worker(send.getRequest(), send.getId());
  • 您的切入點com.xyz.myapp.ServiceImpl.worker()永遠不會匹配,因為它有一個空的參數列表,但是您的方法有參數。 args()在這里無濟於事。
  • 切入點的語法也是錯誤的,因為它沒有指定方法的返回類型,甚至沒有指定* 此外,方法名稱本身還不夠,應將其包含在實際的切入點類型中,例如execution() 也就是說,您想編寫類似以下內容的內容:
@Pointcut("execution(* com.xyz.myapp.ServiceImpl.worker(..)) && args(request, ..)")
private void someOperation(Request request) {}

要攔截引發異常的方法,您可以使用以下代碼(僅在方法是公共的情況下有效):

 @AfterThrowing(pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()",throwing="ex")
         public void doRecoveryActions(NullPointerException ex) {
          // ...
         }

資料來源: Spring AOP

暫無
暫無

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

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