如何定义AspectJ Pointcut以匹配指定方法直接调用的所有方法
可以实现,借助AspectJ提供的cflowbelow和withinCode切入点指示符组合即可满足需求。
实现原理
cflowbelow(切入点):匹配位于指定切入点控制流下方的所有连接点,简单来说就是目标方法执行过程中触发的所有操作withinCode(切入点):限定连接点的代码直接定义在指定方法的代码块内,用来过滤间接调用的场景
具体实现代码
首先定义匹配parentMethod执行的基础切入点,再组合得到直接调用匹配规则:
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; @Aspect public class ParentMethodCallAspect { // 匹配ClassA中parentMethod方法的执行,注意替换为你实际的类全限定名 @Pointcut("execution(* com.yourpackage.ClassA.parentMethod(..))") public void parentMethodExec() {} // 匹配parentMethod直接调用的所有方法的执行时机 @Pointcut("cflowbelow(parentMethodExec()) && withinCode(parentMethodExec()) && execution(* *(..))") public void directMethodCalledByParent() {} // 前置通知示例,可根据需求换用Around/After等其他通知类型 @Before("directMethodCalledByParent()") public void beforeDirectCall(JoinPoint joinPoint) { // 这里可以拿到被调用的方法信息,做自定义逻辑 System.out.println("parentMethod直接调用了方法:" + joinPoint.getSignature().getName()); } }
规则说明
- 上述配置运行后,当
parentMethod被调用时,切面只会匹配到它直接调用的methodX、methodY的执行时机,不会匹配这两个方法内部再间接调用的其他方法 - 如果不需要严格限制直接调用,只要是
parentMethod执行过程中调用的方法都需要匹配,删掉withinCode(parentMethodExec())的条件即可 - 如果只想匹配特定类的方法调用,可以在
execution(* *(..))部分加上类限定,比如改成execution(* com.yourpackage.ClassB.*(..)) || execution(* com.yourpackage.ClassC.*(..))来缩小匹配范围
内容的提问来源于stack exchange,提问作者Tabish Mir
相关产品推荐
相关产品推荐

