在我的情况下,我使用以下advice
:
@Around(value = "@annotation(MyAnnotation) && args(MyArgs)")
一旦将MyAnnotation添加到方法中它就可以正常工作,并且还会检索MyArgs
。
@MyAnnotation(type = MyType.CREATE)
public void add(MyArgs) {
...
}
但在这个post中,它说:
可能会发生的错误
仅使用注释会产生另一个问题,我们在使用模式时不需要考虑这些问题;它会使我们的建议运行两次(或更多次),因为注释切入点没有指定它是否应该在执行或初始化期间运行。
根据我的理解,一旦达到join point
并满足条件似乎正确,建议应该运行(然后我的建议将运行两次 - 调用< / em>和 exeuction )。我应该使用以下建议来避免它。
@Around(value = "@annotation(MyAnnotation) && execution(* *(..)) && args(MyArgs)")
但我调试了我的代码,它只运行一次而不添加 execution(* *(..))
。
这是对的吗?或者它不是advice
运行的方式?
@Nandor是对的,我使用 Spring AOP 而不是 AspectJ 。我开始了一个maven demo,清楚地表明了他的观点。谢谢,Nandor。
答案 0 :(得分:5)
如果你使用的是AspectJ,你的建议会被触发两次,因为切入点表达式
@annotation(MyAnnotation)
匹配方法执行和方法调用连接点。请参阅AspectJ编程指南中的call vs execution。由于您的切入点表达式不限于调用或执行连接点,因此它将匹配两者。如果您实际上在项目中使用了AspectJ,那么您的周围建议将被触发,您将面临在您所指的帖子中被警告的问题。
使用此切入点表达式并不会导致执行两次的周围建议意味着您实际上没有使用AspectJ,而是使用Spring AOP,而只支持方法执行切入点(参见Spring AOP capabilities and goals)
Spring AOP目前仅支持方法执行连接点(建议在Spring bean上执行方法)。
仅适用于公共方法,因为Spring AOP基于代理的特性(除了许多其他限制)。
如果要创建与Spring AOP和AspectJ兼容的切入点表达式,请始终通过添加相应的切入点表达式将切入点限制为方法执行,例如:
@annotation(MyAnnotation) && execution(public * *(..))