繁体   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