aop执行跳过某个方法_简谈前端开发中的AOP(一) -- 前端AOP的实现思路
前言
本意不想用太長的篇幅,來闡述這個(gè)話題。但是有些概念和設(shè)計(jì)思路有必要講清楚,以便于搞清楚其深層次的內(nèi)在邏輯。這是我一直遵從的“知其然,知其所以然”的原則。首先,本文將簡單的闡述一下概念;進(jìn)而,舉例一起探討一下前端AOP實(shí)現(xiàn)方式,以及隨著前端語言ES5、ES6、Typescript的發(fā)展,實(shí)現(xiàn)方式的演變;最后,一起了解一下實(shí)際項(xiàng)目中AOP的應(yīng)用場景、相關(guān)框架以及開發(fā)模式。
什么是AOP?
AOP為Aspect Oriented Programming的縮寫,意為:面向切面編程。主要意圖是將日志記錄,性能統(tǒng)計(jì),安全控制,事務(wù)處理,異常處理等代碼從業(yè)務(wù)邏輯代碼中劃分出來,將它們獨(dú)立到非指導(dǎo)業(yè)務(wù)邏輯的方法中,進(jìn)而改變這些行為的時(shí)候不影響業(yè)務(wù)邏輯的代碼。
簡而言之,就是“優(yōu)雅”的把“輔助功能邏輯”從“業(yè)務(wù)邏輯”中分離解耦。
簡單說一下AOP中的一些概念
確切說是其實(shí)是AspectJ中的相關(guān)概念。AspectJ是一個(gè)擴(kuò)展了Java語言的面向切面的框架。其優(yōu)秀的設(shè)計(jì)思想值得我們參考學(xué)習(xí)。
AspectJ的主要相關(guān)概念有下面這些:
- 連接點(diǎn)(Joinpoint):表示在程序中明確定義的點(diǎn),典型的包括方法調(diào)用,對(duì)類成員的訪問以及異常處理程序塊的執(zhí)行等等
- 切入點(diǎn)(Pointcut):表示一組Joinpoint,這些Joinpoint或是通過邏輯關(guān)系組合起來,或是通過通配、正則表達(dá)式等方式集中起來,它定義了將要放置增強(qiáng)Advice的地方。比如"所有類的submit和reset方法調(diào)用執(zhí)行”
- 切面(Aspect):由切點(diǎn)和增強(qiáng)組成,既包含了增強(qiáng)邏輯的具體實(shí)現(xiàn)和連接點(diǎn)的定義
- 通知/增強(qiáng)(Advice):具體的增強(qiáng)邏輯實(shí)現(xiàn)。通常依據(jù)放置的地方不同,可分為前置通知(Before)、后置返回通知(AfterReturning)、后置異常通知(AfterThrowing)、后置通知(After)與圍繞通知(Around)5種
- 織入(Weaving):將切面應(yīng)用到目標(biāo)對(duì)象從而創(chuàng)建一個(gè)新的代理對(duì)象的過程
為了便于理解,我們可以把一個(gè)業(yè)務(wù)流程比作一個(gè)面包,那么面包切片就是一個(gè)業(yè)務(wù)模塊或者功能。類似于“某個(gè)切面的前面”,“某個(gè)切片的后面”這種描述叫做連接點(diǎn)(Joinpoint);把花生醬、面包、生菜打包成一個(gè)獨(dú)立模塊進(jìn)行邏輯處理,就是一個(gè)切面(Aspect);切面可以定義通知(Advice)、切入點(diǎn)(Pointcut)也即放入通知的連接點(diǎn);把切面跟面包結(jié)合,從而制成三明治這個(gè)過程叫做織入(Weaving)。
早期前端AOP的簡單實(shí)現(xiàn)
多數(shù)的前端的編程思想、設(shè)計(jì)模式、框架以及工具,都是參考服務(wù)端已經(jīng)應(yīng)用成熟的設(shè)計(jì)思路實(shí)現(xiàn)的,AOP也不例外。我們前面已經(jīng)講過一些AspectJ的相關(guān)概念。很明顯,下面我們打算參照其用法,逐步實(shí)現(xiàn)前端AOP編程。
通過前面對(duì)AspectJ的概念的分析,可以得出一個(gè)簡略的總結(jié):AOP編程就是在不破壞原有代碼的基礎(chǔ)上,在原執(zhí)行動(dòng)作之前或者之后,加入一段自定義的動(dòng)作。這里的“原有動(dòng)作”是函數(shù),“增強(qiáng)的動(dòng)作”也是函數(shù),把他們打包成一個(gè)動(dòng)作也是函數(shù)。顯然,基于javascript語言的特性,函數(shù)式編程是實(shí)現(xiàn)前端AOP編程的最佳方式。
看下面的簡單實(shí)現(xiàn):
/**調(diào)用執(zhí)行:
function執(zhí)行結(jié)果
這里面通過傳參匹配到的"oldFn的調(diào)用執(zhí)行"對(duì)應(yīng)切入點(diǎn)(PointCut);before和after對(duì)應(yīng)通知/增強(qiáng)(Advice);創(chuàng)造newFn的過程可以對(duì)應(yīng)織入(Weaving)動(dòng)作。另外,還可以參考AspectJ的用法,簡單模擬一下每個(gè)增強(qiáng)對(duì)應(yīng)的連接點(diǎn)(JoinPoint)信息。
var測(cè)試調(diào)用:
// ......省略執(zhí)行結(jié)果
至此,已經(jīng)可以初見前端AOP編程的雛形。前面例子已經(jīng)簡單實(shí)現(xiàn)過前置通知(Before)和后置終于通知(After)。還有后置返回通知(AfterReturning)、后置異常通知(AfterThrowing)、與圍繞通知(Around)的具體實(shí)現(xiàn)沒有討論。接下來,我們將簡單的模擬實(shí)現(xiàn)一個(gè)簡單完整的AspectJS。
- Before標(biāo)識(shí)的方法為前置方法,在目標(biāo)方法的執(zhí)行之前執(zhí)行,即在連接點(diǎn)之前進(jìn)行執(zhí)行。
- Around環(huán)繞通知方法可以包含上面四種通知方法,環(huán)繞通知的功能最全面。且環(huán)繞通知必須有返回值, 返回值即為目標(biāo)方法的返回值。對(duì)應(yīng)JoinPoint需要附帶可執(zhí)行原執(zhí)行動(dòng)作的方法(invoke)
比如我們需要計(jì)算原函數(shù)的執(zhí)行時(shí)間
function- AfterThrowing異常通知方法只在連接點(diǎn)方法出現(xiàn)異常后才會(huì)執(zhí)行,否則不執(zhí)行。因此對(duì)應(yīng)JoinPoint需要附帶異常參數(shù)(exception)
- AfterReturning當(dāng)連接點(diǎn)方法成功執(zhí)行后,返回通知方法才會(huì)執(zhí)行,如果連接點(diǎn)方法出現(xiàn)異常,則返回通知方法不執(zhí)行。返回通知方法在目標(biāo)方法執(zhí)行成功后才會(huì)執(zhí)行,所以,返回通知方法可以拿到目標(biāo)方法(連接點(diǎn)方法)執(zhí)行后的結(jié)果。因此對(duì)應(yīng)的JoinPoint需要附帶執(zhí)行結(jié)果(result)
- After后置通知方法在連接點(diǎn)方法完成之后執(zhí)行,無論連接點(diǎn)方法執(zhí)行成功還是出現(xiàn)異常,都將執(zhí)行后置方法
下面完整的實(shí)現(xiàn)一下這個(gè)簡略版的AOP工具
/**下面通過一個(gè)簡單的實(shí)例簡單說明。同樣的,我們打算在Person類的run方法的執(zhí)行前后織入增強(qiáng)。按照前面的實(shí)現(xiàn)思路:
function這是針對(duì)單獨(dú)類方法AOP的實(shí)現(xiàn)。顯然這里面存在以下幾個(gè)問題:
- 現(xiàn)實(shí)中不總是針對(duì)一個(gè)應(yīng)用類的一個(gè)方法做AOP處理
- 應(yīng)該如何如何定義切面Aspect,也就是上面定advices
- 一個(gè)應(yīng)用類不總是對(duì)應(yīng)一個(gè)切面Aspect
- 一個(gè)切面Aspect也不總是對(duì)應(yīng)一個(gè)應(yīng)用類
綜上所述,更合理的應(yīng)用類織入切面Aspect應(yīng)該是這樣的:
var這里引發(fā)出另外一個(gè)問題,切面類Aspect應(yīng)該是什么樣子?應(yīng)該如何定義?
前面講過,切面包括切點(diǎn)(joinPoint)和通知(advice),方法名稱對(duì)應(yīng)切點(diǎn)joinPoint,相應(yīng)的增強(qiáng)函數(shù)對(duì)應(yīng)通知advice。那么一個(gè)簡單的Aspect應(yīng)該是這樣子:
var相應(yīng)的我們創(chuàng)建一個(gè)織入Weaving函數(shù)
var看一下完整的實(shí)例:
function至此,一個(gè)簡略版的前端AOP工具已經(jīng)完成了。但是這里依然存在一些問題。
比如:
- 上面討論過的應(yīng)用類和Aspect多對(duì)多關(guān)系
- Aspect類的實(shí)現(xiàn)
- ES6和Typescript的出現(xiàn)與發(fā)展對(duì)前端AOP開發(fā)帶來哪些影響?
- AOP的應(yīng)用以及遇到的問題及其解決辦法
由于篇幅所限我們將在下一篇文章繼續(xù)討論,繼續(xù)完善我們上面實(shí)現(xiàn)的AOP工具。
這僅僅是一個(gè)開始,我們需要討論的還有很多......
總結(jié)
以上是生活随笔為你收集整理的aop执行跳过某个方法_简谈前端开发中的AOP(一) -- 前端AOP的实现思路的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。