Spring AoP 在切入点中以特定字符串结尾的任何包中引用所有 类 中的所有方法

Spring AoP Reference all methods from all classes in any package ending in a certain String in a pointcut

我想引用所有 类 中所有 类 中以切入点中的某个字符串结尾的任何包中的所有 public 方法。

我试过:

@Pointcut("execution(public * *.*SomeString.*(..))")

编辑:由于我想引用的 类 都来自应用程序上下文,我知道我可以使用 bean()

来做到这一点
@Pointcut("bean(*SomeString)")    

但我更愿意使用 execution()。

*.*SomeString的问题在于它只在第一个包级别中寻找classes,例如foo.BarSomeStringhello.MySomeString,但不在 foo.aaa.bbb.BarSomeStringhello.xxx.MySomeString.

等子包中

如果包名完全无关,可以使用通配符:

execution(public * *..*SomeString.*(..))

顺便说一句,如果你使用完整的 AspectJ 而不是 Spring AOP,你可以使用这个快捷方式(我不知道为什么 Spring AOP 不喜欢它,因为它也使用 AspectJ 库对于切入点匹配):

execution(public * *SomeString.*(..))

如果你想在它下面定义一个基础后台和子包,你可以使用..语法:

execution(public * de.scrum_master..*SomeString.*(..))

后者的替代方法是使用 within() 来限制包:

execution(public * *(..)) && within(de.scrum_master..*SomeString)

顺便说一下,在 AspectJ 中你确实需要 execution() 切入点,因为它有更多的切入点类型,但在 Spring AOP 中隐式地所有切入点都是执行切入点,因为这是唯一的连接点类型Spring AOP 支持,因为它基于代理的性质。所以你也可以只写:

within(de.scrum_master..*SomeString)

对于基于接口的代理(Java 动态代理)这是相同的,因为只支持 public 方法。这里唯一的细微差别是对于 CGLIB 代理(当代理 classes,而不是接口,或通过配置所有代理时)这也将匹配受保护和包范围的方法。


稍微跑题了,下面是如何对 classes 做同样的事情,但 methods 有一个特殊的后缀:

execution(public * *SomeString(..))

如果您还想限制 package/class 范围,您可以将其合并:

execution(public * *SomeString(..)) && within(de.scrum_master..*)

或等价地:

execution(public * de.scrum_master..*SomeString(..))

因此,如果您想同时限制包、class 和方法名称,您可以这样做:

execution(public * de.scrum_master..*Controller.*SomeString(..))

或等价地:

execution(public * *SomeString(..)) && within(de.scrum_master..*Controller)

您可以组合 executionwithin 切入点来满足您的需要。

您可以使用 within 到 select 类 的所有方法以这样的特定子字符串结尾:

within(*..*SomeString)

您可以使用 execution 到 select 所有 public 方法,如下所示:

execution(public * *(..))

合并后,它们将 select 所有 类 的所有 public 方法以某个子字符串 .

结尾
within(*..*SomeString) && execution(public * *(..))