JAVA advice annotation 会运行两次吗?

标签 java aspectj

在我的例子中,我使用了以下建议:

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

一旦将 MyAnnotation 添加到方法中,它就可以正常工作,并且 MyArgs 也将被检索。

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

但是在这个post ,它说:

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.

根据我的理解,一旦到达 join point 并且满足条件,建议应该运行(然后我上面的 advice 将运行两次 - < em>调用 和执行)。我应该使用以下建议来避免它。

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

但是我调试了我的代码,它只运行一次而没有添加execution(* *(..))

这样对吗?或者这不是 advice 运行的方式?

2018-04-16 更新

@Nandor 是对的,我使用的是 Spring AOP 而不是 AspectJ。我启动了一个 maven demo清楚地表明了他的观点。谢谢你,南多尔。

最佳答案

如果您使用的是 AspectJ,您的建议将被触发两次,因为切入点表达式

@annotation(MyAnnotation)

匹配方法执行 和方法调用 连接点。参见 call vs execution在 AspectJ 编程指南中。由于您的切入点表达式不限于调用执行 连接点,因此它将匹配两者。如果您实际上在您的项目中使用了 AspectJ,那么您的 around advice 将被触发,并且您将面临您在您所指的帖子中被警告的问题。

事实上,使用这个切入点表达式不会导致周围建议执行两次,这意味着您实际上没有使用 AspectJ,而是使用 Spring AOP,它只支持方法执行切入点(参见 Spring AOP capabilities and goals)

Spring AOP currently supports only method execution join points (advising the execution of methods on Spring beans).

并且仅适用于公共(public)方法,因为 Spring AOP 的基于代理的性质(除了许多其他限制)。

如果要创建与 Spring AOP 和 AspectJ 行为相同的切入点表达式,请确保始终通过添加相应的切入点表达式将切入点约束为方法执行,例如:

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

关于JAVA advice annotation 会运行两次吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49786603/

相关文章:

JavaFX TabPane : How to listen to selection changes

java - Spring 3,在非托管类中注入(inject) bean 的可配置注释的风险?

java - 重载方法的切入点

java - @Transactional 不适用于 AspectJ

java - Maven AspectJ 编织 NullPointerException

java - 编译时编织配置

java - Android 谷歌地图内部 fragment

java - 如何通过 XPages Java Bean 上传和保存附件

java - 如何序列化 HttpHandler 类中的对象

java - 如何让 Maven 设置(并保持最新)我的 Eclipse 项目的构建路径?