当前位置: 首页 > 知识库问答 >
问题:

Spring AspectJ,方法执行前的pointcut,其中方法或类被注释

孙昂然
2023-03-14

注释:

@Inherited
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String value() default "";
}

方面:

@Aspect
public class MyAspect {
    @Pointcut("execution(@com.myco.MyAnnotation * com.myco.somepackage..*.*(..))")
    public void atExecution() { }

    @Before("atExecution() && @annotation(myAnnotation)")
    public void myAdvice(JoinPoint joinPoint, MyAnnotation myAnnotation) {
        ...
    }
}

有什么想法吗?谢了。

共有1个答案

段干瑞
2023-03-14

虽然可以制定一个同时匹配直接注释的方法和注释类型的方法的切入点,但不能在绑定注释值的地方创建切入点和/或建议(即在建议代码中使用注释值)。

@Aspect
public class MyAspect {

    @Pointcut("execution(@com.myco.MyAnnotation * com.myco.somepackage..*.*(..))")
    public void atExecutionOfAnnotatedMethod() {}

    @Pointcut("execution(* (@com.myco.MyAnnotation com.myco.somepackage..*).*(..))")
    public void atExecutionOfMethodsOfAnnotatedClass() {}

    @Before("atExecutionOfAnnotatedMethod() && @annotation(myAnnotation)")
    public void myAdviceForMethodAnnotation(JoinPoint joinPoint, MyAnnotation myAnnotation) {
        System.out.println("myAdviceForMethodAnnotation: " + myAnnotation.value());
    }

    @Before("atExecutionOfMethodsOfAnnotatedClass() && @this(myAnnotation)")
    public void myAdviceForTypeAnnotation(JoinPoint joinPoint, MyAnnotation myAnnotation) {
        System.out.println("myAdviceForTypeAnnotation: " + myAnnotation.value());
    }

    //      /* the following pointcut will result in "inconsistent binding" errors */
    //      @Pointcut("(atExecutionOfAnnotatedMethod() && @annotation(myMethodAnnotation)) || (atExecutionOfMethodsOfAnnotatedClass() && @this(myTypeAnnotation))")
    //      public void combinedPointcut(MyAnnotation myMethodAnnotation, MyAnnotation myTypeAnnotation) {}

}

要组合两个独立的切入点(atexecutionofannotatedMethodatexecutionofmethodsofnotatedClass),我们必须使用OR()构造。由于OR构造不能保证这两个注释绑定中的任何一个都将在通知执行时出现,因此它们都将导致编译错误(不一致的绑定)。您仍然可以在单独的建议中处理这两种情况,您也可以将实际的建议代码委托给公共方法以避免重复。在这种情况下,您需要处理类型和方法都用@myAnnotation注释的情况,因为这将匹配两个切入点,并将导致您的方法受到两个建议的双重建议,因此处理代码的常见建议将执行两次。

如果您需要将这两种情况结合在一起,同时防止双重通知目标代码,则需要在方法级注释和类级注释之间设置优先级。基于特定性原则,我建议走方法级注释优先于类级注释的路线。您的方面如下所示:

@Aspect
public class MyCombinedAspect {

    @Pointcut("execution(@com.myco.MyAnnotation * com.myco.somepackage..*.*(..))")
    public void atExecutionOfAnnotatedMethod() {}

    @Pointcut("execution(* (@com.myco.MyAnnotation com.myco.somepackage..*).*(..))")
    public void atExecutionOfMethodsOfAnnotatedClass() {}

    @Before("atExecutionOfAnnotatedMethod() && !atExecutionOfMethodsOfAnnotatedClass() && @annotation(myAnnotation)")
    public void myAdviceForMethodAnnotation(JoinPoint joinPoint, MyAnnotation myAnnotation) {
        handleBeforeExecution(joinPoint, myAnnotation);
    }

    @Before("atExecutionOfMethodsOfAnnotatedClass() && !atExecutionOfAnnotatedMethod() && @this(myAnnotation)")
    public void myAdviceForTypeAnnotation(JoinPoint joinPoint, MyAnnotation myAnnotation) {
        handleBeforeExecution(joinPoint, myAnnotation);
    }

    @Before("atExecutionOfMethodsOfAnnotatedClass() && atExecutionOfAnnotatedMethod() && @annotation(myMethodAnnotation)")
    public void myAdviceForDoublyAnnotated(JoinPoint joinPoint, MyAnnotation myMethodAnnotation) {
        handleBeforeExecution(joinPoint, myMethodAnnotation);
    }

    protected void handleBeforeExecution(JoinPoint joinPoint, MyAnnotation myAnnotation) {
        System.out.println(myAnnotation.value());
    }
 类似资料:
  • 对于用@X注释的类中的方法或用@X注释的方法,我需要一个切入点。我还需要注释对象。如果类和方法都被注释,我更喜欢将方法注释作为参数。 我尝试了以下操作,这会产生“绑定不一致”的警告。(为什么不直接将其设置为null?) 以下内容创建了“穿过切入点中的“||”的参数x的不明确绑定”警告。(在我看来,这不一定有意义:为什么不绑定第一个短路评估?) 如果存在类和方法注释,则将前面的尝试拆分为两个,自然会

  • 示例: 当我在测试套件中执行这些类时,首先执行类1的@test,然后打开一个新的浏览器实例,其中执行类2的@test。现在执行类1的第二个@test,然后执行类2的第二个@test。注意:在这种情况下测试并行为false。需要知道为什么会这样。我希望第一类的执行在第二类开始之前完成。我想不通。我做了一些变通办法,但没有奏效。 提前道谢。

  • 问题内容: 我需要 在类中使用@X注释的方法或使用@X注释的方法的切入点 。我还 需要注释对象 。如果同时注释了类和方法,则 我更喜欢将方法注释作为参数 。 我尝试了以下操作,这将创建“不一致的绑定”警告。(为什么不将它们设置为null?) 下面创建“跨’||’的参数x的模糊绑定 在切入点”警告。(我认为这并不一定有意义:为什么不绑定第一个短路评估?) 如果存在类和方法注释,则将先前的尝试自然地分

  • 我想在类级别上有注释,将执行注释类中的每个方法的建议。这可能吗。

  • 我有以下问题: 我已经为安全性创建了注释: 在我具有类之间的继承性的情况下,是否也有可能所有类都具有@Security注释来获得最具体的定义? 约西