gpt4 book ai didi

Spring AspectJ,方法执行之前的切入点,其中注释了方法或类

转载 作者:行者123 更新时间:2023-12-04 00:11:37 25 4
gpt4 key购买 nike

我正在尝试通过 Spring Aop AspectJ 样式获取注释的值,其中注释可以在类或方法上。我尝试了很多不同的东西,但只有在方法上有注释时我才能让它工作。我真的很想在类上注释 ONCE - 但建议类的所有方法 - 并在建议中访问类注释的值。这是我结束的地方:

注释:

@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) {
...
}
}

有什么想法吗?谢谢。

最佳答案

简答

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

@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) {}

}

一些细节

要组合两个单独的切入点(atExecutionOfAnnotatedMethodatExecutionOfMethodsOfAnnotatedClass),我们必须使用 OR (||) 构造。由于 OR 构造不保证两个注释绑定(bind)中的任何一个将在建议执行时出现,因此它们都将导致编译错误(不一致的绑定(bind))。您仍然可以在单独的建议中处理这两种情况,您也可以将实际的建议代码委托(delegate)给一个通用方法以避免重复。在这种情况下,您需要注意类型和方法都被 @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());
}

关于Spring AspectJ,方法执行之前的切入点,其中注释了方法或类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34290131/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com