Spring AOP - AspectJ错误:参数(s)会话在'||'之间的模糊绑定在切入点

时间:2011-12-14 08:43:50

标签: maven aspectj spring-aop

当我从命令行或从eclipse运行mvn包时出现此错误。

奇怪的是,如果我运行mvn package 3-4次,那么错误就不再显示了,构建成功完成!同样在eclipse中,文件中有一个红色的'x',其中定义了切入点(在包浏览器中),但是当我打开文件时没有错误。切入点。两个切入点'||'使用的是:

@Pointcut("((execution(gr.diassa.dslibweb.data.dto.GenericGrid gr.diassa.dslibweb.controller.*.*(..)) && args(session,..)) || (execution(gr.diassa.dslibweb.data.dto.GenericGrid gr.diassa.dslibweb.controller.*.*(..)) && args(..,session))) && excludeInitControllerMethods()")
public void controllerActionForMethodsThatReturnJsonString(HttpSession session) {

}

@Pointcut("((execution(org.springframework.web.servlet.ModelAndView gr.diassa.dslibweb.controller.*.*(..)) && args(session,..)) || (execution(org.springframework.web.servlet.ModelAndView gr.diassa.dslibweb.controller.*.*(..)) && args(..,session))) && excludeInitControllerMethods()")
public void controllerActionForMethodsThatReturnModelAndView(HttpSession session) {

}

我在任何地方都找不到类似的东西,之前有人处理过这个问题吗?

1 个答案:

答案 0 :(得分:4)

这既是编译器指出的有效问题,也是实际POV中AspectJ的缺点。

需要注意的一点是:您不仅要使用切入点来绑定建议,还要同时尝试从匹配的切入点中获取一些参数值。现在的问题是,您正在定义两个备选方案(使用||) - 不幸的是,可能发生两种情况都适用。这对于匹配和定义建议不是问题。但是由于你想选择一个参数值,当两个分支都有效时,AspectJ不知道该怎么做。

在您的示例中,可能是一个方法,它在参数列表的开头和结尾处带有两个不同的 session参数。这种方法将匹配切入点的两个替代分支。在这种情况下,AspectJ假定返回哪个会话?

虽然所有这一切在逻辑上都是正确的,但从实际的POV来看,这往往是一个缺点。

  • 通常 - 当您开始编写此类切入点时非常常见 - 您恰好知道您想要的特定对象始终是相同的,或者至少差异并不重要。或者您假设您从第一个适用的分支机构获得匹配("短路评估")并且不关心进一步的匹配
  • 在我遇到的所有情况下,AspectJ都无法弄清楚两个分支是不相交的,即使在这可以静态派生的情况下也是如此。
  • 另见此Bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=121805(2005年报告,2014年重新开放)。看起来实现这些东西是棘手的,很难做到正确。此错误也可能解释为什么不能一致地检测到这个问题(应该是这样)

因此,唯一的补救措施是将切入点拆分为每个分支的不同切入点,并为每个分支编写单独的建议。通常,您希望从所有这些建议委托一个通用的实现方法。 Uggly,但在实践中让你解决这个问题