AspectJ自定義註解之埋點(三)
阿新 • • 發佈:2018-12-21
介紹
埋點,我們公司有很多核心的方法,要給大資料做統計需要做埋點,埋點其實就是將使用者操作這部分業務邏輯的記錄下來,給大資料作分析,前端埋點就是插入上報資訊的功能,後端埋點一般是Api埋點,埋點程式碼和業務邏輯沒有任何關係,如果入侵是寫入(手動插入埋點程式碼),將來的維護成本大大提升,更何況埋所有的點選事件呢?工作量很大,所以AspectJ做埋點在合適不過了
onClick事件埋點
這還不簡單?晒程式碼
findViewById(R.id.btn_test).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ToastUtil.getInstance().showToast(getApplicationContext(), "點選事件發生點選");
}
});
@Before("execution(* android.view.View.OnClickListener.onClick(android.view.View))")
public void hookOnClicknPoint(JoinPoint joinPoint) {
Log.d("wyz", "點選事件");
}
自定義埋點
自定義埋點,也就是如果我想對此方法進行埋點,我只需要新增物件的自定義的註解,然後就會注入埋點邏輯
什麼是註解
對於很多初次接觸的開發者來說應該都有這個疑問?Annontation是Java5開始引入的新特徵,中文名稱叫註解。它提供了一種安全的類似註釋的機制,用來將任何的資訊或元資料(metadata)與程式元素(類、方法、成員變數等)進行關聯。為程式的元素(類、方法、成員變數)加上更直觀更明瞭的說明,這些說明資訊是與程式的業務邏輯無關,並且供指定的工具或框架使用。Annontation像一種修飾符一樣,應用於包、型別、構造方法、方法、成員變數、引數及本地變數的宣告語句中。 Java註解是附加在程式碼中的一些元資訊,用於一些工具在編譯、執行時進行解析和使用,起到說明、配置的功能。註解不會也不能影響程式碼的實際邏輯,僅僅起到輔助性的作用。包含在 java.lang.annotation 包中。
元註解
java.lang.annotation提供了四種元註解,專門註解其他的註解(在自定義註解的時候,需要使用到元註解):
暱稱 | 解釋 |
---|---|
@Documented | 註解是否將包含在JavaDoc中 |
@Retention | 定義該註解的生命週期,RetentionPolicy引數包括 |
@Target | 表示該註解用於什麼地方。預設值為任何元素,表示該註解用於什麼地方。可用的ElementType引數包括 |
@Inherited | 是否允許子類繼承該註解 |
Retention型別 | 介紹 |
---|---|
RetentionPolicy.SOURCE | 在編譯階段丟棄。這些註解在編譯結束之後就不再有任何意義,所以它們不會寫入位元組碼。@Override, @SuppressWarnings都屬於這類註解。 |
RetentionPolicy.CLASS | 在類載入的時候丟棄。在位元組碼檔案的處理中有用。註解預設使用這種方式 |
RetentionPolicy.RUNTIME | 始終不會丟棄,執行期也保留該註解,因此可以使用反射機制讀取該註解的資訊。我們自定義的註解通常使用這種方式 |
ElementType型別 | 介紹 |
---|---|
ElementType.CONSTRUCTOR | 用於描述構造器 |
ElementType.FIELD | 成員變數、物件、屬性(包括enum例項) |
ElementType.LOCAL_VARIABLE | 用於描述區域性變數 |
ElementType.METHOD | 用於描述方法 |
ElementType.PACKAGE | 用於描述包 |
ElementType.PARAMETER | 用於描述引數 |
ElementType.TYPE | 用於描述類、介面(包括註解型別) 或enum宣告 |
定義註解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
int id();
String description() default "我是預設描述";
}
這裡說下,剛開始的時候,我考過,這個註解定義在哪裡合適呢?我一開始寫在了主專案中,最後發現不合適,需要定義在AspectJ的libray中比較合適
編寫AspectJ程式碼
/**
* 自定義註解埋點
*/
@Before("execution(@com.mmvoice.aspectj.anantation.MyAnnotation * *(..))")
public void buriedPoint(JoinPoint joinPoint) {
// 獲取註解
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
// 這也就是為何我要將MyAnnotation定義到,library中了,這類要使用
MyAnnotation annotation = signature.getMethod().getAnnotation(MyAnnotation.class);
Log.d("wyz", "埋點邏輯執行-資料-" + annotation.id() + " " + annotation.description());
}
可以看到編寫過濾條件的時候,註解簽名寫了一個@
表示式 | 描述 |
---|---|
註解切入點表示式 | advice (@Annotation 訪問訪問 返回型別 切入點路徑) |
路徑切入點表示式 | advice( 訪問訪問 返回型別 切入點路徑) |