我有这样的服务代码:
@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{
}
我做错了什么?
使用Spring 3.1.3在Java 7中编写代码。
我尝试过另一种方式。我使用'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)'但我在调试器中看到方法签名中运行时缺少注释。所以问题依然存在。
答案 0 :(得分:3)
<强> e.g。在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
}
答案 1 :(得分:2)
你的第二次切入点
@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
作为您的建议方法参数。
答案 2 :(得分:1)
可能您的注释没有运行时保留期:
@Retention(RetentionPolicy.RUNTIME)
public @interface WithAuthorization {}