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