我正在尝试实现一个记录器方面,它可以跨应用程序中的多个包应用。它是一个大型 Spring Web 应用程序,具有许多模块。每个模块都有自己的 Controller 、服务和 DAO。我定义的切入点针对包中每个类的所有公共(public)方法。 Controller 为 public * com.abc.module1.controllers.*.*(..)
,public * com.abc.module1.services.*.*(..)
用于服务,public * com.abc.module1.daos.*.*(..)
用于 module1 中的 DAO。我有大约 30 个这样的模块。所以问题是,为了涵盖所有这些模块,我必须为每个模块定义切入点。所有模块都遵循相同的包结构。有没有一种方法可以指定可以覆盖放置在不同模块中的所有 Controller 、服务的切入点? Spring AOP 允许在包名称中使用通配符吗?
最佳答案
我建议阅读AspectJ documentation ,例如
那么你就不需要在这里问这样的问题了。
无论如何,这是解决问题的方法(我添加换行符是为了提高可读性):
execution(public * com.abc..controllers..*(..)) ||
execution(public * com.abc..services..*(..)) ||
execution(public * com.abc..daos..*(..))
或者:
(
within(com.abc..controllers..*) ||
within(com.abc..services..*) ||
within(com.abc..daos..*)
) &&
execution(public * *(..))
如果你使用 Spring AOP 而不是成熟的 AspectJ,你可以让它变得更简单,因为 Spring AOP 基本上只知道 execution()
而没有其他切入点,如 call()
、构造函数执行、set()
/get()
等
within(com.abc..controllers..*) ||
within(com.abc..services..*) ||
within(com.abc..daos..*)
使用 JDK 动态代理(当您的组件实现接口(interface)时默认),这只会针对公共(public)方法调用。使用 CGLIB 代理,它还将针对 protected 和包私有(private)的代理。顺便说一句,如果您以后从 Spring AOP 迁移到 AspectJ,您还需要将简单切入点升级为上述更明确的切入点之一。
关于java - Spring AOP 切入点表达式中包名称的通配符支持,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49884801/