Mic*_*ews 3 spring aspectj spring-aop
我正在尝试通过 Spring Aop AspectJ 样式获取注释的值,其中注释可以在类或方法上。我尝试了很多不同的东西,但只有当注释在方法上时我才能让它工作。我真的很想在类上注释 ONCE - 但建议该类的所有方法 - 并在建议中访问类注释的值。这是我结束的地方:
注解:
@Inherited
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value() default "";
}
Run Code Online (Sandbox Code Playgroud)
方面:
@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) {
...
}
}
Run Code Online (Sandbox Code Playgroud)
有什么想法吗?谢谢。
虽然您可以制定一个切入点来同时 匹配直接带注释的方法和带注释类型的方法,但您不能在绑定注释值的地方创建切入点和/或通知(即在通知代码中使用注释值) )。
@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) {}
}
Run Code Online (Sandbox Code Playgroud)
要组合两个单独的切入点 (atExecutionOfAnnotatedMethod和atExecutionOfMethodsOfAnnotatedClass),我们必须使用 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());
}
Run Code Online (Sandbox Code Playgroud)