[英]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{
}
我究竟做錯了什么?
代碼是用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.