我有以下切入点表达式:

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

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

我浏览了Spring AOP文档,但找不到使切入点失败并带有异常的方法。有办法吗?

最佳答案

安东尼奥100%是正确的,这里没有错误。切入点只是说:“如果碰巧找到与该描述匹配的连接点,请在此处应用我的方面建议”。


连接点匹配是在Spring AOP中的运行时完成的。因此,这是一种固有的动态事物。
具有加载时编织(LTW)的AspectJ也是如此。类加载器总是有机会加载新类,然后将它们动态切入编织的切入点和方面代码。因此,您永远不会知道您已经完成了方面编织。您何时会发出警告或错误?
如果您将AspectJ与编译时编织(CTW)一起使用,并且在编译过程中建议的切入点根本无法与任何连接点匹配时,AspectJ编译器将发出警告Xlint:adviceDidNotMatch。但是考虑一下,它永远不会只是信息或警告,因为如果您编译一个方面模块,以后您想将其应用于多个应用程序或一个应用程序中的其他模块,则无论您使用的是CTW还是LTW ,只有在编织这些模块时才能找到匹配的连接点。


因此,这没有错误,否则您将永远无法使用方面库或LTW。方面的整体思想是它们独立于应用程序代码。

此外,如果将99%的apply方法重命名为applyTo,但是出于某种原因(出于意图或疏忽),请保留一个apply方法,该切入点仍将匹配,因此也不会产生您的假设错误。您的错误不是语法错误而是语义错误,一个方面的织工如何知道这一点?正如安东尼奥所说,谨慎重构。在这种特殊情况下,您可以将切入点更改为apply*,然后它既可以匹配applyapplyTo,也可以匹配applyMagic,这也许是您不想要的。

Stultuske匹配注释而不是方法名称的想法是我所说的“穷人的AOP方法”,因为它仍然在整个代码库中散布与AOP相关的信息,因此并没有实现AOP的承诺,即不仅摆脱了代码纠结而且还有散射。现在,分散仅适用于注释,而不适用于内联方法代码。如果您根本没有在应用程序代码中看到AOP,则我个人最喜欢AOP,除非您希望声明性地应用某些功能,并且出于某种原因希望在源代码中使用@Transactional等注释来记录AOP。但这只是一个问题,我可能仍会尝试将声明放入方面切入点而不是应用程序中。仅当整体匹配模式太复杂而无法在切入点中处理时,我才可以使用注释。国际海事组织(IMO)误导了注释和方面,甚至使某种“ AOP设计模式”成为一种误导,因而被过度使用。该模式具有很好的用途,但远少于我所看到的。

09-28 08:34