带批注方法或带批注类中的方法的切点

2022-09-02 20:54:28

我需要为用@X注释的类中的方法或用@X注释的方法提供切点。我还需要注释对象。如果类和方法都带有注释,我更喜欢将方法注释作为参数

我尝试了以下方法,这会产生“绑定不一致”警告。(为什么不直接将它们设置为空?

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

下面创建一个“参数 x 在切入点的 '||' 上的不明确绑定”警告。(在我看来,这不一定有意义:为什么不绑定第一个短路评估?

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

如果存在类和方法批注,则将上一次尝试拆分为两次自然会导致两个方法调用。

我知道我可以通过反射和我想要的注释来获得方法和类,并带有这样的切点:

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

但我不愿意。

是否有任何“一个切入点,一种方法,一个注释参数”,用于我的要求的解决方案,不需要反射?


答案 1

不完全是,但差不多。您将需要两个切入点,两个建议,但您可以将工作委托给单个方法。下面是它的外观:

@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. 执行任何用 @X 注释的方法,任何类中的任何返回类型都在任何包中,以获得第一个建议
  2. 在用 @X 注释的任何类中执行具有任何返回类型的任何方法

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

在具有类型注释的类型中定义关联代码的任何连接点X

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

主题具有类型批注的任何连接点X

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


答案 2

推荐