日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

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

發(fā)布時(shí)間:2025/6/17 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【AOP 面向切面编程】Android Studio 使用 AspectJ 监控方法运行 ( 定义连接点注解 | 定义 Aspect 切面 | 定义切入点 | 逐个处理切入点的各个连接点 ) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

  • 一、定義 Join Point 連接點(diǎn)注解
  • 二、定義 Aspect 切面
    • 1、定義 Aspect 切面
    • 2、定義 Aspect 切面
    • 3、逐個(gè)處理切入點(diǎn)的各個(gè)連接點(diǎn)
    • 4、完整 Aspect 切面代碼
  • 三、使用 AspectJ 埋點(diǎn)并監(jiān)控方法性能





一、定義 Join Point 連接點(diǎn)注解



要監(jiān)控哪些方法 , 首先要對該方法添加注解 , 該注解標(biāo)記哪些方法是 Join Point 連接點(diǎn) , 所有被該注解標(biāo)記的方法構(gòu)成 一組 Join Point 連接點(diǎn) , 即 Point Cut 切入點(diǎn) ;

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;/*** 該注解標(biāo)記哪些方法是 Join Point 連接點(diǎn)* 所有被該注解標(biāo)記的方法構(gòu)成 一組 Join Point 連接點(diǎn) , 即 Point Cut 切入點(diǎn)*/ @Retention(RetentionPolicy.RUNTIME) // 注解保留到運(yùn)行時(shí) @Target(ElementType.METHOD) // 注解作用于方法上 public @interface Monitor {String value(); }

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

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



二、定義 Aspect 切面




1、定義 Aspect 切面


Aspect 切面 : Java 中的類聲明是 對事物的抽象 , AspectJ 中的 Aspect 切面就是 對切面的抽象 , 其中包含了 Point Cut 切入點(diǎn) 和 Advice 通知 ; 使用 @Aspect 注解修飾 ;

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

2、定義 Aspect 切面


Point Cut 切入點(diǎn) : 一組 Join Point 連接點(diǎn) , 通過 邏輯關(guān)系 / 正則表達(dá)式 / 通配符 等關(guān)系組合 , 定義了 Advice 通知發(fā)生的位置 ;


解析 "execution(@com.example.aop_demo.Monitor * *(..))" 匹配規(guī)則 :

  • @com.example.aop_demo.Monitor 表示帶該注解的方法
  • 第 1 個(gè) * 表示在所有包下面
  • 第 2 個(gè) * 表示在所有類下面
  • (..) 表示所有方法 , 參數(shù)不限

整體含義 : 所有的包 所有的類 中 , 帶有 @com.example.aop_demo.Monitor 注解的方法 , 都是 Pointcut 切入點(diǎn) , 每個(gè)方法都是一個(gè) JoinPoint 連接點(diǎn) ;


/*** 定義切入點(diǎn)* "execution(@com.example.aop_demo.Monitor * *(..))" 表示* 帶有 @com.example.aop_demo.Monitor 注解的* 所有包下面的 所有類中的 所有方法, 方法參數(shù)不限* 上述方法組成 切入點(diǎn) , 每個(gè)方法都是一個(gè) Join Point 連接點(diǎn)** execution(@com.example.aop_demo.Monitor * *(..)) 解讀* - @com.example.aop_demo.Monitor 表示帶該注解的方法* - 第 1 個(gè) * 表示在所有包下面* - 第 2 個(gè) * 表示在所有類下面* - (..) 表示所有方法 , 參數(shù)不限** 所有的包 所有的類 中 , 帶有 @com.example.aop_demo.Monitor 注解的方法 , 都是 Pointcut 切入點(diǎn)* 上述每個(gè)方法都是一個(gè) Join Point 連接點(diǎn)*/@Pointcut("execution(@com.example.aop_demo.Monitor * *(..))")public void pointCut(){}

3、逐個(gè)處理切入點(diǎn)的各個(gè)連接點(diǎn)


@Around("pointCut()") 注解中傳入的注解屬性是 切入點(diǎn) 的名稱 , 就是上面定義的 public void pointCut(){} 方法對應(yīng)的 Pointcut 切入點(diǎn) ;


獲取 JoinPoint 連接點(diǎn) 對應(yīng) 方法的相關(guān)屬性 :

  • 獲取方法上的注解 , 以及注解屬性 : 首先獲取方法簽名 , 在回去方法簽名對應(yīng)的 Method 對象 , 獲取該對象上的注解 , 根據(jù)注解調(diào)用注解中定義的獲取屬性的接口方法 ;
// 獲取方法上 @Monitor("onClick") 注解中的注解屬性 字符串// 獲取被 @Monitor("onClick") 注解修飾的方法的 方法簽名MethodSignature signature = (MethodSignature) joinPoint.getSignature();// 根據(jù)方法簽名獲取方法// 然后獲取方法上的 @Monitor 注解Monitor annotation = signature.getMethod().getAnnotation(Monitor.class);// 獲取 @Monitor("onClick") 注解中的注解屬性String value = annotation.value();
  • 獲取方法名稱 : signature.getDeclaringType() 就是方法所在的類的字節(jié)碼類對象 , 然后調(diào)用 getSimpleName 方法即可獲取類名 ;
// 獲取方法名稱String className = signature.getDeclaringType().getSimpleName();
  • 獲取方法所在類名稱 : 直接調(diào)用方法簽名的 getName 方法 , 即可獲取方法名 ;
// 獲取方法所在的類名String methodName = signature.getName();

調(diào)用 joinPoint.proceed() 方法 , 可同步執(zhí)行該具體的方法 , 方法的上下可以進(jìn)行用戶自己的埋點(diǎn)業(yè)務(wù)邏輯 , 如統(tǒng)計(jì)方法執(zhí)行耗時(shí)等操作 ;

// 執(zhí)行具體的方法result = joinPoint.proceed();

代碼示例 :

/*** 逐個(gè)處理 Pointcut 切入點(diǎn) 中的 JoinPoint 連接點(diǎn)* 一個(gè)一個(gè)處理** @Around("pointCut()") 注解中傳入的注解屬性是* 切入點(diǎn)的名稱 , 就是上面定義的 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();// 根據(jù)方法簽名獲取方法// 然后獲取方法上的 @Monitor 注解Monitor annotation = signature.getMethod().getAnnotation(Monitor.class);// 獲取 @Monitor("onClick") 注解中的注解屬性String value = annotation.value();// 獲取方法名稱String className = signature.getDeclaringType().getSimpleName();// 獲取方法所在的類名String methodName = signature.getName();// 記錄方法執(zhí)行開始時(shí)間long startTime = System.currentTimeMillis();// 執(zhí)行具體的方法result = joinPoint.proceed();// 記錄方法執(zhí)行結(jié)束時(shí)間long endTime = System.currentTimeMillis();Log.i(TAG, "執(zhí)行 " + className + " 中的 " + methodName +" 方法花費(fèi)了 " + (endTime - startTime) + " ms , 注解屬性為 " + value );} catch (Throwable throwable) {throwable.printStackTrace();}return result;}

4、完整 Aspect 切面代碼


package com.example.aop_demo;import android.util.Log;import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature;/*** 定義 Aspect 切面*/ @Aspect public class MonitorAspect {private static final String TAG = "MonitorAspect";/*** 定義切入點(diǎn)* "execution(@com.example.aop_demo.Monitor * *(..))" 表示* 帶有 @com.example.aop_demo.Monitor 注解的* 所有包下面的 所有類中的 所有方法, 方法參數(shù)不限* 上述方法組成 切入點(diǎn) , 每個(gè)方法都是一個(gè) Join Point 連接點(diǎn)** execution(@com.example.aop_demo.Monitor * *(..)) 解讀* - @com.example.aop_demo.Monitor 表示帶該注解的方法* - 第 1 個(gè) * 表示在所有包下面* - 第 2 個(gè) * 表示在所有類下面* - (..) 表示所有方法 , 參數(shù)不限** 所有的包 所有的類 中 , 帶有 @com.example.aop_demo.Monitor 注解的方法 , 都是 Pointcut 切入點(diǎn)* 上述每個(gè)方法都是一個(gè) Join Point 連接點(diǎn)*/@Pointcut("execution(@com.example.aop_demo.Monitor * *(..))")public void pointCut(){}/*** 逐個(gè)處理 Pointcut 切入點(diǎn) 中的 JoinPoint 連接點(diǎn)* 一個(gè)一個(gè)處理** @Around("pointCut()") 注解中傳入的注解屬性是* 切入點(diǎn)的名稱 , 就是上面定義的 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();// 根據(jù)方法簽名獲取方法// 然后獲取方法上的 @Monitor 注解Monitor annotation = signature.getMethod().getAnnotation(Monitor.class);// 獲取 @Monitor("onClick") 注解中的注解屬性String value = annotation.value();// 獲取方法名稱String className = signature.getDeclaringType().getSimpleName();// 獲取方法所在的類名String methodName = signature.getName();// 記錄方法執(zhí)行開始時(shí)間long startTime = System.currentTimeMillis();// 執(zhí)行具體的方法result = joinPoint.proceed();// 記錄方法執(zhí)行結(jié)束時(shí)間long endTime = System.currentTimeMillis();Log.i(TAG, "執(zhí)行 " + className + " 中的 " + methodName +" 方法花費(fèi)了 " + (endTime - startTime) + " ms , 注解屬性為 " + value );} catch (Throwable throwable) {throwable.printStackTrace();}return result;} }



三、使用 AspectJ 埋點(diǎn)并監(jiān)控方法性能



監(jiān)控 public void textClick(View view) 方法性能 , 在該方法上使用 @Monitor 注解 , 該注解已經(jīng)被定義為切入點(diǎn) , 所有的包 所有的類 中 , 帶有 @com.example.aop_demo.Monitor 注解的方法 , 都是 Pointcut 切入點(diǎn) , 應(yīng)用執(zhí)行時(shí) , 會自動(dòng)執(zhí)行埋點(diǎn)業(yè)務(wù)邏輯 , 這里是在方法執(zhí)行前后 , 分別記錄時(shí)間 , 最終計(jì)算出方法的耗時(shí) ;

package com.example.aop_demo;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle; import android.os.SystemClock; import android.view.View;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}@Monitor("textClick")public void textClick(View view) {// 休眠 500 msSystemClock.sleep(500);} }

執(zhí)行結(jié)果 : 點(diǎn)擊按鈕 , 觸發(fā) textClick 方法 , 觸發(fā)了埋點(diǎn)邏輯 , 自動(dòng)計(jì)算出了該方法的執(zhí)行耗時(shí) ;

2021-09-22 22:23:04.954 12492-12492/com.example.aop_demo I/MonitorAspect: 執(zhí)行 MainActivity 中的 textClick 方法花費(fèi)了 501 ms , 注解屬性為 textClick

總結(jié)

以上是生活随笔為你收集整理的【AOP 面向切面编程】Android Studio 使用 AspectJ 监控方法运行 ( 定义连接点注解 | 定义 Aspect 切面 | 定义切入点 | 逐个处理切入点的各个连接点 )的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。