带注释的方法或带注释的方法的切入点 类

Pointcut for annotated methods or methods in annotated classes

我需要 classes 中用 @X 注释的方法或用 @X 注释的方法的切入点。我还需要注释对象。如果 class 和方法都被注释 我更喜欢将方法注释作为参数.

我尝试了以下操作,它创建了一个 "inconsistent binding" 警告。 (为什么不直接将它们设置为空?)

@Around("@annotation(methodLevelX) || @within(classLevelX)")
public Object advise(ProceedingJoinPoint pjp, X methodLevelX, X classLevelX)

以下创建一个 "ambiguous binding of parameter(s) x across '||' in pointcut" 警告。 (我认为这不一定有意义:为什么不绑定第一个短路评估?)

@Around("@annotation(x) || @within(x)")
public Object advise(ProceedingJoinPoint pjp, X x)

如果 class 和方法注释存在,将之前的尝试一分为二自然会导致两个方法调用。

我知道我可以通过反射获得方法和 class 以及我想要的带有切入点的注释:

@Around("@annotation(com.package.X) || @within(com.package.X)")

但我不想这样做。

是否有任何"one pointcut, one method, one annotation argument"不需要反射就能满足我的要求的解决方案?

不完全是,但差不多。您将需要两个切入点、两个建议,但您可以将工作委托给一个方法。这是它的样子:

@Aspect
public class AnyAspectName {

    @Pointcut("execution(@X * *.*(..))")
    void annotatedMethod() {}

    @Pointcut("execution(* (@X *).*(..))")
    void methodOfAnnotatedClass() {}

    @Around("annotatedMethod() && @annotation(methodLevelX)")
    public Object adviseAnnotatedMethods(ProceedingJoinPoint pjp, X methodLevelX) 
            throws Throwable {
        return aroundImplementation(pjp, methodLevelX);
    }

    @Around("methodOfAnnotatedClass() && !annotatedMethod() && @within(classLevelX)")
    public Object adviseMethodsOfAnnotatedClass(ProceedingJoinPoint pjp, X classLevelX) 
            throws Throwable {
        return aroundImplementation(pjp, classLevelX);
    }

    public Object aroundImplementation(ProceedingJoinPoint pjp, X annotation) 
            throws Throwable {
        return pjp.proceed();
    }

}

请注意,除了拆分 @annotation()@within() 切入点外,我还对生成的切入点添加了限制,以免它们过于宽泛。我想你想要 方法执行 连接点,所以我添加了所需的切入点表达式,将其限制为方法执行。他们匹配

  1. 在任何 class 中执行任何 @X 注释的任何方法,任何 return 类型在任何包中 第一个建议
  2. 在第二个用 @X 注释的任何 class 中使用任何 return 类型执行任何方法。

进一步限制 @within(X)@annotation(X) 会派上用场,因为 @within(X) 本身会匹配

any join point where the associated code is defined in a type with an annotation of type X

这将包括方法执行方法调用构造函数执行构造函数调用预初始化静态初始化初始化字段集字段获取异常处理程序 类型的连接点(但并非所有连接点都对 around advices 有效)。同样,@annotation(X) 本身就意味着

any join point where the subject has an annotation of type X

这也可能意味着前面提到的大部分连接点,具体取决于注释的目标类型。