弹簧 AOP - AspectJ 错误:切入点中跨'||'的参数会话绑定不明确



当我从命令行或从eclipse运行mvn包时,我得到这个错误。

奇怪的是,如果我运行mvn包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) {
}

我没有在任何地方找到类似的东西,有人以前处理过这个吗?

这既是编译器指出的一个有效问题,也是AspectJ从实际POV来看的一个缺点。

需要注意的是:您不仅使用切入点绑定通知,同时还尝试从匹配的切入点获取一些参数值。现在的问题是,您正在定义两个可选的场景(使用||)——不幸的是,如果可能两个场景都适用。对于匹配和定义通知来说,这不是问题。但是由于您想要选择一个参数值,当两个分支都有效时,AspectJ不知道该怎么做。

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

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

  • 通常——当您开始编写这样的切入点时非常常见——您只是碰巧知道您想要的特定对象总是相同的,或者至少差异无关紧要。或者您假设您从第一个适用分支("短路评估")获得匹配,并且不关心进一步的匹配
  • 在我碰到的所有情况下,AspectJ 无法找出两个分支是不相交的,即使在可以静态派生的情况下也是如此。
  • 参见此Bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=121805(2005年报告,2014年重新开放)。看起来实现这些东西很棘手,很难做好。这个Bug也可以解释为什么这个问题没有被一致地检测到(因为它应该是)
因此,唯一的补救方法是将切入点拆分为每个分支的不同切入点,并为每个分支编写单独的通知。通常你想要从所有这些建议中委托给一个公共实现方法。但是在实践中可以解决这个问题

最新更新