简体   繁体   English

JAVA 咨询注解会运行两次吗?

[英]JAVA advice annotation will run twice?

In my case, I am using the following advice :就我而言,我使用以下advice

  @Around(value = "@annotation(MyAnnotation)  && args(MyArgs)")

and it works fine once the MyAnnotation is added to the method and MyArgs will also retrieved.一旦将 MyAnnotation 添加到方法中, MyArgs可以正常工作并且MyArgs也将被检索。

  @MyAnnotation(type = MyType.CREATE)
  public void add(MyArgs) { 
  ...
  }

But in this post , it says:但在这篇文章中,它说:

The errors that can and will occur可能会发生的错误

Using only annotations creates another problem that we don't need to think about while using patterns;仅使用注释会产生另一个我们在使用模式时不需要考虑的问题; It will make our advice run twice(or more) , because the annotation pointcut don't specify if it should be run during execution or initialization.它会使我们的建议运行两次(或更多) ,因为注释切入点没有指定它是否应该在执行或初始化期间运行。

To my understanding, it seems right once the join point reached and the condition is met, the advice should run (then my advice above will run twice - the call and the exeuction ).据我了解,这似乎是正确的,一旦join point达到并满足条件,建议应该运行(当时我的上述建议将运行两次-呼叫exeuction)。 And I should use the following advice to avoid it.我应该使用以下建议来避免它。

  @Around(value = "@annotation(MyAnnotation)  && execution(* *(..)) && args(MyArgs)")

But I debugged my code, it only runs once without adding execution(* *(..)) .但是我调试了我的代码,它只运行一次而不添加execution(* *(..))

Is this right?这是对的吗? Or it's not the way in which advice runs?或者这不是advice运行方式?

Updated 2018-04-16 2018-04-16 更新

@Nandor is right, I was using Spring AOP instead of AspectJ . @Nandor 是对的,我使用的是Spring AOP而不是AspectJ I started a maven demo clearly demonstating his point.我开始了一个 Maven 演示,清楚地证明了他的观点。 Thank you, Nandor.谢谢你,南多。

If you were using AspectJ, your advice would be triggered twice, because the pointcut expression如果您使用的是 AspectJ,您的通知将被触发两次,因为切入点表达式

@annotation(MyAnnotation)

matches both method execution and method call join points.匹配方法执行和方法调用连接点。 See call vs execution in the AspectJ programming guide.请参阅 AspectJ 编程指南中的调用与执行 Since your pointcut expression is not restricted to either call or execution join points, it will match both.由于您的切入点表达式不限于调用执行连接点,它将匹配两者。 If you were actually using AspectJ in your project, your around advice would be triggered for both and you would face the issue you were warned about in the post you are referring to.如果您实际上在项目中使用了 AspectJ,那么您的周围建议将被触发,并且您将面临在您所指的帖子中被警告的问题。

The fact that using this pointcut expression doesn't result in the around advice executing twice means that you are in fact not using AspectJ and you're using Spring AOP instead, which only supports method execution pointcuts (see Spring AOP capabilities and goals )使用这个切入点表达式不会导致围绕建议执行两次这一事实意味着您实际上没有使用 AspectJ 而是使用 Spring AOP,它只支持方法执行切入点(请参阅Spring AOP 功能和目标

Spring AOP currently supports only method execution join points (advising the execution of methods on Spring beans). Spring AOP 当前仅支持方法执行连接点(建议在 Spring bean 上执行方法)。

and only for public methods, because of the proxy based nature of Spring AOP (besides many other limitations).并且仅用于公共方法,因为 Spring AOP 基于代理的性质(除了许多其他限制)。

If you want to create pointcut expressions that would behave the same with both Spring AOP and AspectJ, make sure to always constrain the pointcut to method execution by adding the corresponding pointcut expression, for example:如果要创建与 Spring AOP 和 AspectJ 行为相同的切入点表达式,请确保始终通过添加相应的切入点表达式将切入点限制为方法执行,例如:

@annotation(MyAnnotation) && execution(public * *(..))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM