如何使不正确的切入点表达式抛出异常?

How can I make an incorrect pointcut expression throw an exception?

我有以下切入点表达式:

@Pointcut("execution(* apply(..))")

现在,如果将建议的方法重命名为 applyTo,则切入点不再正确,建议将永远不会触发。建议的失败不会引起注意,因为不正确的切入点不会在应用程序启动时或运行时引发任何异常。

我查看了 Spring AOP 文档,但找不到使切入点因异常而失败的方法。有办法吗?

Antonio 是 100% 正确的,这里没有错误。切入点只是说:"If you happen to find joinpoints matching this description, apply my aspect advice there".

  • 连接点匹配是在运行时在 Spring AOP 中完成的。所以它本质上是一个动态的东西。
  • 具有加载时织入 (LTW) 的 AspectJ 也是如此。类加载器总是有机会加载新的 类 ,然后动态匹配切入点和嵌入其中的方面代码。所以你永远不会知道你是 "done" 相位编织。您什么时候会发出警告或错误?
  • 如果您将 AspectJ 与编译时编织 (CTW) 一起使用,如果在编译期间建议的切入点根本无法匹配任何连接点,AspectJ 编译器将发出警告 Xlint:adviceDidNotMatch。但是想一想,它永远不会超过一条信息或一条警告,因为如果您编译了一个方面模块,您以后想要将其应用于多个应用程序或一个应用程序中的其他模块,无论您使用的是 CTW 还是 LTW ,匹配的连接点只会在编织这些模块时找到。

所以这不是错误,否则你永远无法使用方面库或 LTW。方面的整体思想是它们独立于应用程序代码。

此外,如果您将 99% 的 apply 方法重命名为 applyTo 但出于某种原因 - 故意或疏忽 - 保留单个 apply 方法,切入点仍会匹配,所以你的假设错误也不会产生。您的错误不是语法上的而是语义上的,方面编织者怎么知道呢?正如安东尼奥所说,小心重构。在这种特殊情况下,您可以将切入点更改为 apply*,然后它会同时匹配 applyapplyTo,但也会匹配您可能不想要的 applyMagic

Stultuske 的想法是匹配注释而不是方法名称,我称之为 "poor man's approach to AOP" 因为它仍然在整个代码库中散布与 AOP 相关的信息,因此没有兑现 AOP 的承诺,不仅要摆脱代码纠缠但也分散。分散现在仅适用于注释而不适用于内联方法代码。如果您在应用程序代码中根本看不到 AOP,我个人最喜欢 AOP,除非您希望以声明方式应用某些功能,并且出于某种原因在源代码中用 @Transactional 等注释记录下来。但这是一个品味问题,我可能仍会尝试将声明放入方面切入点而不是应用程序中。只有当整体匹配模式太复杂而无法在切入点中处理时,我才可能改用注释。 IMO,链接注释和方面甚至制作某种 "AOP design pattern" 的广泛做法被误导并因此被过度使用。该模式有其良好的用途,但比我看到的要少得多。