【AOP 面向切面编程】Android Studio 使用 AspectJ 监控方法运行 ( 定义连接点注解 | 定义 Aspect 切面 | 定义切入点 | 逐个处理切入点的各个连接点 )(一)

简介: 【AOP 面向切面编程】Android Studio 使用 AspectJ 监控方法运行 ( 定义连接点注解 | 定义 Aspect 切面 | 定义切入点 | 逐个处理切入点的各个连接点 )(一)

文章目录

一、定义 Join Point 连接点注解

二、定义 Aspect 切面

1、定义 Aspect 切面

2、定义 Aspect 切面

3、逐个处理切入点的各个连接点

4、完整 Aspect 切面代码

三、使用 AspectJ 埋点并监控方法性能





一、定义 Join Point 连接点注解


要监控哪些方法 , 首先要对该方法添加注解 , 该注解标记哪些方法是 Join Point 连接点 , 所有被该注解标记的方法构成 一组 Join Point 连接点 , 即 Point Cut 切入点 ;


package com.example.aop_demo;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * 该注解标记哪些方法是 Join Point 连接点
 *      所有被该注解标记的方法构成 一组 Join Point 连接点 , 即 Point Cut 切入点
 */
@Retention(RetentionPolicy.RUNTIME) // 注解保留到运行时
@Target(ElementType.METHOD) // 注解作用于方法上
public @interface Monitor {
    String value();
}


注解的用法如下 : 如果想要监控下面的 public void textClick(View view) 方法 , 在该方法上添加 @Monitor 注解即可 ;


 

@Monitor("textClick")
    public void textClick(View view) {
        // 休眠 500 ms
        SystemClock.sleep(500);
    }






二、定义 Aspect 切面



1、定义 Aspect 切面


Aspect 切面 : Java 中的类声明是 对事物的抽象 , AspectJ 中的 Aspect 切面就是 对切面的抽象 , 其中包含了 Point Cut 切入点 和 Advice 通知 ; 使用 @Aspect 注解修饰 ;


/**
 * 定义 Aspect 切面
 */
@Aspect
public class MonitorAspect {
}


2、定义 Aspect 切面


Point Cut 切入点 : 一组 Join Point 连接点 , 通过 逻辑关系 / 正则表达式 / 通配符 等关系组合 , 定义了 Advice 通知发生的位置 ;



解析 "execution(@com.example.aop_demo.Monitor * *(..))" 匹配规则 :


@com.example.aop_demo.Monitor 表示带该注解的方法

第 1 个 * 表示在所有包下面

第 2 个 * 表示在所有类下面

(..) 表示所有方法 , 参数不限

整体含义 : 所有的包 所有的类 中 , 带有 @com.example.aop_demo.Monitor 注解的方法 , 都是 Pointcut 切入点 , 每个方法都是一个 JoinPoint 连接点 ;



 

/**
     * 定义切入点
     * "execution(@com.example.aop_demo.Monitor * *(..))" 表示
     *      带有 @com.example.aop_demo.Monitor 注解的
     *      所有包下面的 所有类中的 所有方法, 方法参数不限
     *      上述方法组成 切入点 , 每个方法都是一个 Join Point 连接点
     *
     * execution(@com.example.aop_demo.Monitor * *(..)) 解读
     *  - @com.example.aop_demo.Monitor 表示带该注解的方法
     *  - 第 1 个 * 表示在所有包下面
     *  - 第 2 个 * 表示在所有类下面
     *  - (..) 表示所有方法 , 参数不限
     *
     *  所有的包 所有的类 中 , 带有 @com.example.aop_demo.Monitor 注解的方法 , 都是 Pointcut 切入点
     *      上述每个方法都是一个 Join Point 连接点
     */
    @Pointcut("execution(@com.example.aop_demo.Monitor * *(..))")
    public void pointCut(){}



3、逐个处理切入点的各个连接点


@Around("pointCut()") 注解中传入的注解属性是 切入点 的名称 , 就是上面定义的 public void pointCut(){} 方法对应的 Pointcut 切入点 ;



获取 JoinPoint 连接点 对应 方法的相关属性 :


获取方法上的注解 , 以及注解属性 : 首先获取方法签名 , 在回去方法签名对应的 Method 对象 , 获取该对象上的注解 , 根据注解调用注解中定义的获取属性的接口方法 ;

       

// 获取方法上 @Monitor("onClick") 注解中的注解属性 字符串
            // 获取被 @Monitor("onClick") 注解修饰的方法的 方法签名
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            // 根据方法签名获取方法
            //      然后获取方法上的 @Monitor 注解
            Monitor annotation = signature.getMethod().getAnnotation(Monitor.class);
            // 获取 @Monitor("onClick") 注解中的注解属性
            String value = annotation.value();


获取方法名称 : signature.getDeclaringType() 就是方法所在的类的字节码类对象 , 然后调用 getSimpleName 方法即可获取类名 ;

       

// 获取方法名称
            String className = signature.getDeclaringType().getSimpleName();


获取方法所在类名称 : 直接调用方法签名的 getName 方法 , 即可获取方法名 ;

       

// 获取方法所在的类名
            String methodName = signature.getName();



调用 joinPoint.proceed() 方法 , 可同步执行该具体的方法 , 方法的上下可以进行用户自己的埋点业务逻辑 , 如统计方法执行耗时等操作 ;


       

// 执行具体的方法
            result = joinPoint.proceed();



代码示例 :


 

/**
     * 逐个处理 Pointcut 切入点 中的 JoinPoint 连接点
     *      一个一个处理
     *
     * @Around("pointCut()") 注解中传入的注解属性是
     *      切入点的名称 , 就是上面定义的 public void pointCut(){} 方法
     *
     * @param joinPoint
     * @return
     */
    @Around("pointCut()")
    public Object processJoinPoint(ProceedingJoinPoint joinPoint) {
        Object result = null;
        try {
            // 获取方法上 @Monitor("onClick") 注解中的注解属性 字符串
            // 获取被 @Monitor("onClick") 注解修饰的方法的 方法签名
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            // 根据方法签名获取方法
            //      然后获取方法上的 @Monitor 注解
            Monitor annotation = signature.getMethod().getAnnotation(Monitor.class);
            // 获取 @Monitor("onClick") 注解中的注解属性
            String value = annotation.value();
            // 获取方法名称
            String className = signature.getDeclaringType().getSimpleName();
            // 获取方法所在的类名
            String methodName = signature.getName();
            // 记录方法执行开始时间
            long startTime = System.currentTimeMillis();
            // 执行具体的方法
            result = joinPoint.proceed();
            // 记录方法执行结束时间
            long endTime = System.currentTimeMillis();
            Log.i(TAG, "执行 " + className + " 中的 " + methodName +
                    " 方法花费了 " + (endTime - startTime) + " ms , 注解属性为 " + value );
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return result;
    }



目录
相关文章
|
Android开发 开发者
Android自定义view之利用drawArc方法实现动态效果
本文介绍了如何通过Android自定义View实现动态效果,重点使用`drawArc`方法完成圆弧动画。首先通过`onSizeChanged`进行测量,初始化画笔属性,设置圆弧相关参数。核心思路是不断改变圆弧扫过角度`sweepAngle`,并调用`invalidate()`刷新View以实现动态旋转效果。最后附上完整代码与效果图,帮助开发者快速理解并实践这一动画实现方式。
344 0
|
安全 数据库 Android开发
在Android开发中实现两个Intent跳转及数据交换的方法
总结上述内容,在Android开发中,Intent不仅是活动跳转的桥梁,也是两个活动之间进行数据交换的媒介。运用Intent传递数据时需注意数据类型、传输大小限制以及安全性问题的处理,以确保应用的健壯性和安全性。
768 11
|
监控 Shell Linux
Android调试终极指南:ADB安装+多设备连接+ANR日志抓取全流程解析,覆盖环境变量配置/多设备调试/ANR日志分析全流程,附Win/Mac/Linux三平台解决方案
ADB(Android Debug Bridge)是安卓开发中的重要工具,用于连接电脑与安卓设备,实现文件传输、应用管理、日志抓取等功能。本文介绍了 ADB 的基本概念、安装配置及常用命令。包括:1) 基本命令如 `adb version` 和 `adb devices`;2) 权限操作如 `adb root` 和 `adb shell`;3) APK 操作如安装、卸载应用;4) 文件传输如 `adb push` 和 `adb pull`;5) 日志记录如 `adb logcat`;6) 系统信息获取如屏幕截图和录屏。通过这些功能,用户可高效调试和管理安卓设备。
11131 2
|
缓存 Java Shell
Android 系统缓存扫描与清理方法分析
Android 系统缓存从原理探索到实现。
1165 15
Android 系统缓存扫描与清理方法分析
|
Java API 微服务
微服务——SpringBoot使用归纳——Spring Boot中的切面AOP处理——Spring Boot 中的 AOP 处理
本文详细讲解了Spring Boot中的AOP(面向切面编程)处理方法。首先介绍如何引入AOP依赖,通过添加`spring-boot-starter-aop`实现。接着阐述了如何定义和实现AOP切面,包括常用注解如`@Aspect`、`@Pointcut`、`@Before`、`@After`、`@AfterReturning`和`@AfterThrowing`的使用场景与示例代码。通过这些注解,可以分别在方法执行前、后、返回时或抛出异常时插入自定义逻辑,从而实现功能增强或日志记录等操作。最后总结了AOP在实际项目中的重要作用,并提供了课程源码下载链接供进一步学习。
1894 0
|
Java 开发者 微服务
微服务——SpringBoot使用归纳——Spring Boot中的切面AOP处理——什么是AOP
本文介绍了Spring Boot中的切面AOP处理。AOP(Aspect Oriented Programming)即面向切面编程,其核心思想是分离关注点。通过AOP,程序可以将与业务逻辑无关的代码(如日志记录、事务管理等)从主要逻辑中抽离,交由专门的“仆人”处理,从而让开发者专注于核心任务。这种机制实现了模块间的灵活组合,使程序结构更加可配置、可扩展。文中以生活化比喻生动阐释了AOP的工作原理及其优势。
677 0
|
Java Unix Linux
Android Studio中Terminal运行./gradlew clean build提示错误信息
遇到 `./gradlew clean build`命令执行出错时,首先应检查错误信息的具体内容,这通常会指向问题的根源。从权限、环境配置、依赖下载、版本兼容性到项目配置本身,逐一排查并应用相应的解决措施。记住,保持耐心,逐步解决问题,往往复杂问题都是由简单原因引起的。
1764 2
|
ARouter 测试技术 API
Android经典面试题之组件化原理、优缺点、实现方法?
本文介绍了组件化在Android开发中的应用,详细阐述了其原理、优缺点及实现方式,包括模块化、接口编程、依赖注入、路由机制等内容,并提供了具体代码示例。
582 3
|
Android开发
【Android 组件化】路由组件 ( 运行时获取 注解处理器 生成的路由表 )(一)
【Android 组件化】路由组件 ( 运行时获取 注解处理器 生成的路由表 )(一)
298 0
|
Android开发
【Android 组件化】路由组件 ( 运行时获取 注解处理器 生成的路由表 )(二)
【Android 组件化】路由组件 ( 运行时获取 注解处理器 生成的路由表 )(二)
217 0

热门文章

最新文章