如何为建议方法提供切入点绑定注释?

How do you provide a pointcut bound annotation to an advice method?

所以我已经为所有方法和特定注释的所有 类 定义了切入点...我想要做的是在每次方法调用时检索注释值。这是我目前所拥有的

@Aspect
public class MyAspect {

    @Pointcut("execution(* my.stuff..*(..))")
    private void allMethods(){}

    @Pointcut("within(@my.stuff.MyAnnotation*)")
    private void myAnnotations(){}

    @Pointcut("allMethods() && myAnnotations()")
    private void myAnnotatedClassMethods(){}

    @Before("myAnnotatedClassMethods()")
    private void beforeMyAnnotatedClassMethods(){
        System.out.println("my annotated class method detected.");
        // I'd like to be able to access my class level annotation's value here.

    }

}

是的,您可以让 Spring AOP 提供注解目标对象的注解值 class。

您必须使用 binding forms documented in the specification 并在您的 @Pointcut 方法中传播参数。

例如

@Pointcut("execution(* my.stuff..*(..))")
private void allMethods() {
}

@Pointcut("@within(myAnnotation)")
private void myAnnotations(MyAnnotation myAnnotation) {
}

@Pointcut("allMethods() && myAnnotations(myAnnotation)")
private void myAnnotatedClassMethods(MyAnnotation myAnnotation) {
}

@Before("myAnnotatedClassMethods(myAnnotation)")
private void beforeMyAnnotatedClassMethods(MyAnnotation myAnnotation){
    System.out.println("my annotated class method detected: " + myAnnotation);
}

Spring,从 myAnnotations 切入点开始,会将 @within 中给出的名称与方法参数匹配,并使用它来确定注释类型。然后通过 myAnnotatedClassMethods 切入点向下传播到 beforeMyAnnotatedClassMethods 建议。

Spring AOP 堆栈将在调用您的 @Before 方法之前查找注释值并将其作为参数传递。


如果您不喜欢上面的解决方案,另一种方法是简单地提供 JoinPoint parameter in your advice method. You can use it to resolve the target instance with getTarget 并使用该值来获取 class 注释。例如,

@Before("myAnnotatedClassMethods()")
private void beforeMyAnnotatedClassMethods(JoinPoint joinPoint) {
    System.out.println("my annotated class method detected: " + joinPoint.getTarget().getClass().getAnnotation(MyAnnotation.class));
}

我不确定如果目标进一步包裹在其他代理中,这将如何表现。注释可能 "hidden" 在代理 class 之后。谨慎使用。