Android中使用AspectJ如何追踪接口全部方法与类的指定方法?
Android AspectJ切点匹配规则使用说明
指定接口所有实现方法的追踪规则
要匹配指定接口的所有实现类的方法,需在切点表达式的接口全限定名后添加+通配符,代表匹配该接口的所有子类/实现类。
正确的切点表达式格式为:execution(* 接口全限定名+.*(..))
示例:匹配com.example.abcd.MyInterface接口所有实现类的所有方法,表达式为:@Pointcut("execution(* com.example.abcd.MyInterface+.*(..))")
指定类特定方法的追踪规则
execution切点的标准结构为:execution(返回值类型 类全限定名.方法名(参数列表)),各位置通配符规则如下:
- 返回值位置写
*代表匹配任意返回值类型 - 方法名位置可使用
*做模糊匹配,比如getName*匹配所有以getName开头的方法 - 参数列表位置写
(..)代表匹配任意数量、任意类型的参数
示例:
- 匹配
com.example.abcd.MyClass中所有以getName开头的方法:@Pointcut("execution(* com.example.abcd.MyClass.getName*(..))") - 匹配
com.example.abcd.MyClass中参数为int的公共方法getNameById:@Pointcut("execution(public String com.example.abcd.MyClass.getNameById(int))")
原代码错误修正
现有代码混淆了切点定义和通知逻辑,存在以下错误:
@Pointcut标注的方法仅用于定义切点,不能添加JoinPoint参数,也不能编写方法体,且方法名不能重复- 日志打印的业务逻辑需要写在
@Before/@After/@Around等通知注解标注的方法中
修正后的完整切面代码如下:
@Aspect public class ActivityLifecycleLogAspect { private static final String TAG = "AspectJTrace"; // 定义切点:匹配MyClass中所有getName开头的方法 @Pointcut("execution(* com.example.abcd.MyClass.getName*(..))") public void myClassGetNamePointcut() {} // 定义切点:匹配MyInterface所有实现类的所有方法 @Pointcut("execution(* com.example.abcd.MyInterface+.*(..))") public void myInterfaceMethodPointcut() {} // 前置通知:MyClass的getName方法执行前打印日志 @Before("myClassGetNamePointcut()") public void logMyClassGetName(JoinPoint joinPoint) { Log.v(TAG, "ABCD:------------- " + joinPoint.toLongString()); // 如需验证参数可通过joinPoint.getArgs()获取方法入参 } // 前置通知:接口实现方法执行前打印日志 @Before("myInterfaceMethodPointcut()") public void logMyInterfaceMethod(JoinPoint joinPoint) { Log.v(TAG, "Interface Function Tracing:------------- " + joinPoint.toLongString()); } // 可选:返回值通知,可打印方法返回值验证数据传输 @AfterReturning(pointcut = "myClassGetNamePointcut()", returning = "result") public void logMethodReturn(JoinPoint joinPoint, Object result) { Log.v(TAG, "方法" + joinPoint.getSignature().getName() + "返回结果:" + result); } }
内容的提问来源于stack exchange,提问作者Aaron Lee
相关产品推荐
相关产品推荐

