AOP(Aspect Oriented Program的首字母縮寫)是一種面向切面編程的思想。這種編程思想是相對於OOP(ObjectOriented Programming即面向對象編程)來講的。html
先來講一下你們熟悉的面向對象編程:面向對象的特色是繼承、多態和封裝。而封裝就要求將功能分散到不一樣的對象中去,這在軟件設計中每每稱爲職責分配。實際上也就是說,讓不一樣的類設計不一樣的方法。這樣代碼就分散到一個個的類中去了。這樣作的好處是下降了代碼的複雜程度,使類可重用。可是面向對象的編程天生有個缺點就是分散代碼的同時,也增長了代碼的重複性。
好比我但願在項目裏面全部的模塊都增長日誌統計模塊,按照OOP的思想,咱們須要在各個模塊裏面都添加統計代碼,可是若是按照AOP的思想,能夠將統計的地方抽象成切面,只須要在切面裏面添加統計代碼就OK了。java
代碼demo連接 github.com/xsfelvis/an…android
APT(Annotation Processing Tool 的簡稱),能夠在代碼編譯期解析註解,結合JavaPoet 生成新的 Java 文件,減小手動的代碼輸入。如今有不少主流庫都用上了 APT,好比 Dagger2, ButterKnife, EventBus3 等
更多能夠參考編譯時註解之APTgit
例如github
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.FIELD)
public @interface BindView {
int value();
}
複製代碼
AutoService會自動在META-INF文件夾下生成Processor配置信息文件,該文件裏就是實現該服務接口的具體實現類。而當外部程序裝配這個模塊的時候,
就能經過該jar包META-INF/services/裏的配置文件找到具體的實現類名,並裝載實例化,完成模塊的注入編程
在Processor中提取註解信息 結合一些手段去處理,好比JavaPoet,或者 JavaPoet使用指南api
JoinPoints(鏈接點),程序中可能做爲代碼注入目標的特定的點。在AspectJ中能夠做爲JoinPoints的地方包括
安全
PointCuts(切入點),其實就是代碼注入的位置。與前面的JoinPoints不一樣的地方在於,其實PointCuts是有條件限定的JoinPoints。好比說,在一個Java源文件中,會有不少的JoinPoints,可是咱們只但願對其中帶有@debug註解的地方纔注入代碼。因此,PointCuts是經過語法標準給JoinPoints添加了篩選條件限定oracle
Advice(通知),其實就是注入到class文件中的代碼片。典型的 Advice 類型有 before、after 和 around,分別表示在目標方法執行以前、執行後和徹底替代目標方法執行的代碼框架
Aspect(切面),Pointcut 和 Advice 的組合看作切面。
注入代碼(advices)到目標位置(joint points)的過程
Javassist做用是在編譯器間修改class文件,與之類似的ASM(熱修復框架女媧)也有這個功能,可讓咱們直接修改編譯後的class二進制代碼,
首先咱們得知道何時編譯完成,而且咱們要趕在class文件被轉化爲dex文件以前去修改。在Transfrom這個api出來以前,想要在項目被打包成dex以前對class進行操做,必須自定義一個Task,而後插入到predex或者dex以前,在自定義的Task中可使用javassist或者asm對class進行操做。而Transform則更爲方便,Transfrom會有他本身的執行時機,不須要咱們插入到某個Task前面。Tranfrom一經註冊便會自動添加到Task執行序列中,而且正好是項目被打包成dex以前。
須要配合自定義 GradlePlugin、TransForm,每每在TransForm期間使用Javassit 去完成一些須要的aop,關於自定義Gradle插件這裏就不繼續展開了
ClassPool、CtClass、CtMethod核心類的使用在這裏展現的很詳細。
一、初始化ClassPool設置 二、經過包名取到對應的CtClass 三、CtMethodi插入代碼塊,寫文件,釋放,結束整個注入代碼過程。
這幾種AOP方式各自最大的特色就是編織代碼的時機不一樣,這個須要在使用的時候根據實際須要來,
上圖中 javaassit和asm也能夠結合apt使用的,好比建立類,不過目前建立類通常都是javapoet,它們只是工具而已 一般aop能夠用來處理如下問題