Spring AoP引用切入点中某个String结尾的任何包中所有类的所有方法

4 java spring spring-aop

我想引用切入点中某个String结尾的任何包中所有类的所有公共方法.

我试过了:

@Pointcut("execution(public * *.*SomeString.*(..))")
Run Code Online (Sandbox Code Playgroud)

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

@Pointcut("bean(*SomeString)")    
Run Code Online (Sandbox Code Playgroud)

但我更喜欢使用execution().

kri*_*aex 5

的问题*.*SomeString是,它仅查找第一包级别,如foo.BarSomeStringhello.MySomeString,但不是在子包,如foo.aaa.bbb.BarSomeStringhello.xxx.MySomeString.

如果包名称完全不相关,则可以使用通配符:

execution(public * *..*SomeString.*(..))
Run Code Online (Sandbox Code Playgroud)

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

execution(public * *SomeString.*(..))
Run Code Online (Sandbox Code Playgroud)

如果要在其下定义基本背面和子包,可以使用以下..语法:

execution(public * de.scrum_master..*SomeString.*(..))
Run Code Online (Sandbox Code Playgroud)

后者的替代方案是使用within()以限制包装:

execution(public * *(..)) && within(de.scrum_master..*SomeString)
Run Code Online (Sandbox Code Playgroud)

顺便说一句,在AspectJ中你真的需要execution()切入点,因为它有更多的切入点类型,但是在Spring AOP中隐含地所有切入点都是执行切入点,因为它是Spring AOP支持的唯一连接点类型,因为它具有基于代理的特性.所以你也可以写:

within(de.scrum_master..*SomeString)
Run Code Online (Sandbox Code Playgroud)

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


稍微偏离主题,这里是如何不对类而不是具有特殊后缀的方法做同样的事情:

execution(public * *SomeString(..))
Run Code Online (Sandbox Code Playgroud)

如果您还想限制包/类范围,您可以将它组合起来:

execution(public * *SomeString(..)) && within(de.scrum_master..*)
Run Code Online (Sandbox Code Playgroud)

或等效地:

execution(public * de.scrum_master..*SomeString(..))
Run Code Online (Sandbox Code Playgroud)

因此,如果您想立即限制package,class和mathod名称,请执行以下操作:

execution(public * de.scrum_master..*Controller.*SomeString(..))
Run Code Online (Sandbox Code Playgroud)

或等效地:

execution(public * *SomeString(..)) && within(de.scrum_master..*Controller)
Run Code Online (Sandbox Code Playgroud)