国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

淺談Android面向切面編程(AOP)

2019-12-12 01:40:09
字體:
供稿:網(wǎng)友

一、簡述

1、AOP的概念

如果你用java做過后臺(tái)開發(fā),那么你一定知道AOP這個(gè)概念。如果不知道也無妨,套用百度百科的介紹,也能讓你明白這玩意是干什么的:

AOP為Aspect Oriented Programming的縮寫,意為:面向切面編程,通過預(yù)編譯方式和運(yùn)行期動(dòng)態(tài)代理實(shí)現(xiàn)程序功能的統(tǒng)一維護(hù)的一種技術(shù)。AOP是OOP的延續(xù),是軟件開發(fā)中的一個(gè)熱點(diǎn),也是Spring框架中的一個(gè)重要內(nèi)容,是函數(shù)式編程的一種衍生范型。利用AOP可以對(duì)業(yè)務(wù)邏輯的各個(gè)部分進(jìn)行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可重用性,同時(shí)提高了開發(fā)的效率。

2、項(xiàng)目場景

項(xiàng)目開發(fā)過程中,可能會(huì)有這樣的需求,需要我們在方法執(zhí)行完成后,記錄日志(后臺(tái)開發(fā)中比較常見~),或是計(jì)算這個(gè)方法的執(zhí)行時(shí)間,在不使用AOP的情況下,我們可以在方法最后調(diào)用另一個(gè)專門記錄日志的方法,或是在方法體的首尾分別獲取時(shí)間,然后通過計(jì)算時(shí)間差來計(jì)算整個(gè)方法執(zhí)行所消耗的時(shí)間,這樣也可以完成需求。那如果不只一個(gè)方法要這么玩怎么辦?每個(gè)方法都寫上一段相同的代碼嗎?后期處理邏輯變了要怎么辦?最后老板說這功能不要了我們還得一個(gè)個(gè)刪除?

很明顯,這是不可能的,我們不僅僅是代碼的搬運(yùn)工,我們還是有思考能力的軟件開發(fā)工程師。這么low的做法絕對(duì)不干,這種問題我們完全可以用AOP來解決,不就是在方法前和方法后插入一段代碼嗎?AOP分分鐘搞定。

3、AOP的實(shí)現(xiàn)方式

要注意了,AOP僅僅只是個(gè)概念,實(shí)現(xiàn)它的方式(工具和庫)有以下幾種:

  1. AspectJ: 一個(gè) JavaTM 語言的面向切面編程的無縫擴(kuò)展(適用Android)。
  2. Javassist for Android: 用于字節(jié)碼操作的知名 java 類庫 Javassist 的 Android 平臺(tái)移植版。
  3. DexMaker: Dalvik 虛擬機(jī)上,在編譯期或者運(yùn)行時(shí)生成代碼的 Java API。
  4. ASMDEX: 一個(gè)類似 ASM 的字節(jié)碼操作庫,運(yùn)行在Android平臺(tái),操作Dex字節(jié)碼。

本篇的主角就是AspectJ,下面就來看看AspectJ方式的AOP如何在Android開發(fā)中進(jìn)行使用吧。

二、AspectJ的引入

對(duì)于eclipse與Android Studio的引入是不一樣的,本篇只介紹Android Studio如何引入AspectJ,eclipse請(qǐng)自行百度。Android Studio需要在app模塊的build.gradle文件中引入,總共分為3個(gè)步驟:

1)添加核心依賴

dependencies {  ...  compile 'org.aspectj:aspectjrt:1.8.9'}

2)編寫gradle編譯腳本

buildscript {  repositories {    mavenCentral()  }  dependencies {    classpath 'org.aspectj:aspectjtools:1.8.9'    classpath 'org.aspectj:aspectjweaver:1.8.9'  }}

AspectJ需要依賴maven倉庫。

3)添加gradle任務(wù)

dependencies {  ...}// 貼上面那段沒用的代碼是為了說明:下面的任務(wù)代碼與dependencies同級(jí)import org.aspectj.bridge.IMessageimport org.aspectj.bridge.MessageHandlerimport org.aspectj.tools.ajc.Mainfinal def log = project.loggerfinal def variants = project.android.applicationVariantsvariants.all { variant ->  if (!variant.buildType.isDebuggable()) {    log.debug("Skipping non-debuggable build type '${variant.buildType.name}'.")    return;  }  JavaCompile javaCompile = variant.javaCompile  javaCompile.doLast {    String[] args = ["-showWeaveInfo",             "-1.8",             "-inpath", javaCompile.destinationDir.toString(),             "-aspectpath", javaCompile.classpath.asPath,             "-d", javaCompile.destinationDir.toString(),             "-classpath", javaCompile.classpath.asPath,             "-bootclasspath", project.android.bootClasspath.join(File.pathSeparator)]    log.debug "ajc args: " + Arrays.toString(args)    MessageHandler handler = new MessageHandler(true);    new Main().run(args, handler);    for (IMessage message : handler.getMessages(null, true)) {      switch (message.getKind()) {        case IMessage.ABORT:        case IMessage.ERROR:        case IMessage.FAIL:          log.error message.message, message.thrown          break;        case IMessage.WARNING:          log.warn message.message, message.thrown          break;        case IMessage.INFO:          log.info message.message, message.thrown          break;        case IMessage.DEBUG:          log.debug message.message, message.thrown          break;      }    }  }}

直接粘貼到build.gradle文件的末尾即可,不要嵌套在別的指令中。

三、AOP的基本知識(shí)

在使用AspectJ之前,還是需要先介紹下AOP的基本知識(shí),熟悉的看官可以跳過這部分。

1、AOP術(shù)語

  1. 通知、增強(qiáng)處理(Advice):就是你想要的功能,也就是上面說的日志、耗時(shí)計(jì)算等。
  2. 連接點(diǎn)(JoinPoint):允許你通知(Advice)的地方,那可就真多了,基本每個(gè)方法的前、后(兩者都有也行),或拋出異常是時(shí)都可以是連接點(diǎn)(spring只支持方法連接點(diǎn))。AspectJ還可以讓你在構(gòu)造器或?qū)傩宰⑷霑r(shí)都行,不過一般情況下不會(huì)這么做,只要記住,和方法有關(guān)的前前后后都是連接點(diǎn)。
  3. 切入點(diǎn)(Pointcut):上面說的連接點(diǎn)的基礎(chǔ)上,來定義切入點(diǎn),你的一個(gè)類里,有15個(gè)方法,那就有十幾個(gè)連接點(diǎn)了對(duì)吧,但是你并不想在所有方法附件都使用通知(使用叫織入,下面再說),你只是想讓其中幾個(gè),在調(diào)用這幾個(gè)方法之前、之后或者拋出異常時(shí)干點(diǎn)什么,那么就用切入點(diǎn)來定義這幾個(gè)方法,讓切點(diǎn)來篩選連接點(diǎn),選中那幾個(gè)你想要的方法。
  4. 切面(Aspect):切面是通知和切入點(diǎn)的結(jié)合。現(xiàn)在發(fā)現(xiàn)了吧,沒連接點(diǎn)什么事,連接點(diǎn)就是為了讓你好理解切點(diǎn)搞出來的,明白這個(gè)概念就行了。通知說明了干什么和什么時(shí)候干(什么時(shí)候通過before,after,around等AOP注解就能知道),而切入點(diǎn)說明了在哪干(指定到底是哪個(gè)方法),這就是一個(gè)完整的切面定義。
  5. 織入(weaving) 把切面應(yīng)用到目標(biāo)對(duì)象來創(chuàng)建新的代理對(duì)象的過程。
  6. 引入(introduction) 允許我們向現(xiàn)有的類添加新方法屬性。這不就是把切面(也就是新方法屬性:通知定義的)用到目標(biāo)類中嗎
  7. 目標(biāo)(target) 引入中所提到的目標(biāo)類,也就是要被通知的對(duì)象,也就是真正的業(yè)務(wù)邏輯,他可以在毫不知情的情況下,被咋們織入切面。二自己專注于業(yè)務(wù)本身的邏輯。
  8. 代理(proxy) 怎么實(shí)現(xiàn)整套AOP機(jī)制的,都是通過代理,這個(gè)一會(huì)兒給細(xì)說。
  9. 目標(biāo)對(duì)象 主站蜘蛛池模板: 英山县| 昔阳县| 民乐县| 昔阳县| 遂川县| 科技| 定陶县| 同仁县| 延津县| 临沂市| 新疆| 清水县| 曲阳县| 柯坪县| 双江| 漳平市| 宁津县| 达拉特旗| 临潭县| 乌审旗| 衡山县| 都匀市| 彝良县| 三穗县| 团风县| 龙泉市| 垣曲县| 百色市| 保康县| 新源县| 三台县| 巴彦县| 乌兰县| 金坛市| 尼勒克县| 大田县| 越西县| 谢通门县| 房产| 宁蒗| 宁陕县|