簡體   English   中英

Spring AOP用於接口和其中的注釋方法

[英]Spring AOP for interface and for annotated methods within it

我有這樣的服務代碼:

@Component
public class MyService implements com.xyz.WithSession {

    public void someMethodWhichDoesNotNeedAutorization() {
        // code S1
    }

    @com.xyz.WithAuthorization
    public void someMethodWhichNeedAutorization() {
        // code S2
    }
}

和這樣的方面:

@Aspect
public class MyAspect {

    @Before("target(com.xyz.WithSession)")
    public void adviceBeforeEveryMethodFromClassImplementingWithSession() {
        // code A1
    }

    @Before("target(com.xyz.WithSession) && @annotation(com.xyz.WithAuthorization)")
    public void adviceBeforeWithAuthorizationMethodFromClassImplementingWithSession() {
        // code A2
    }

注釋看起來像:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface WithAuthorization{
}
  • 在代碼S1 - OK之前調用代碼A1
  • 在代碼S2之前調用代碼A1 - OK
  • 在代碼S2之前沒有調用代碼A2 - 不行

我究竟做錯了什么?

代碼是用Java 3.1.3編寫的。

更新

我嘗試過另一種方式。 我使用'Around'建議而不是'Before'和'After'來訪問ProceedingJoinPoint。 在這個建議中,我用反射檢查方法是否有注釋'com.xyz.WithAuthorization':

private boolean isAnnotated(ProceedingJoinPoint proceedingJoinPoint) {
    MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
    return signature.getMethod().isAnnotationPresent(com.xyz.WithAuthorization);
}

我的注釋有'@Retention(RetentionPolicy.RUNTIME)',但我在調試器中看到方法簽名中運行時缺少注釋。 所以問題依然存在。

在Spring 鏈接中的參考

例如在Spring參考中

@Before("com.xyz.lib.Pointcuts.anyPublicMethod() && @annotation(auditable)")
public void audit(Auditable auditable) {
    AuditCode code = auditable.value();
    // ...
}

執行AccountService接口定義的任何方法:

execution(* com.xyz.service.AccountService.*(..))

任何連接點(僅在Spring AOP中執行方法),其中執行方法具有@Transactional注釋:

@annotation(org.springframework.transaction.annotation.Transactional)

我建議你用......

@Before("execution(* com.xyz.WithSession.*(..)) && @annotation(authorization)")
public void adviceBeforeWithAuthorizationMethodFromClassImplementingWithSession(WithAuthorization authorization) {
    // code A2
}

你的第二個切入點

@Before("target(com.xyz.WithSession) && @annotation(com.xyz.WithAuthorization)")

以兩種方式失敗。 首先是

target(com.xyz.WithSession)

只匹配類,而不是方法。 所以像@Xstian指出你應該使用的東西

execution(* com.whatever.MyService.*(..))

匹配MyService類中的所有方法。

第二個問題是

@annotation(com.xyz.WithAuthorization)

其中參數應該是與通知中的參數名稱匹配的名稱。 因此,您使用@annotation(someArgumentName) ,然后將com.xyz.WithAuthorization someArgumentName作為您的通知方法參數。

可能您的注釋沒有運行時保留:

@Retention(RetentionPolicy.RUNTIME)
public @interface WithAuthorization {}

暫無
暫無

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

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