長(zhǎng)沙免費(fèi)網(wǎng)站排名seo觀察網(wǎng)
什么是AOP
?????????AOP是面向切面,面向切面編程,是通過(guò)預(yù)編譯方式和運(yùn)行期動(dòng)態(tài)代理實(shí)現(xiàn)程序功能的統(tǒng)一維護(hù)的一種技術(shù)。對(duì)多個(gè)對(duì)象共同行為封裝成一個(gè)模塊叫切面,然后某個(gè)方法為切點(diǎn)。
????????通俗的講:就是在一些代碼中做重復(fù)操作的時(shí)候,我們?yōu)榱藢?shí)現(xiàn)代碼的復(fù)用性,統(tǒng)一去處理這些工作,讓后讓我們得操作自然的嵌入(用自定義注解)到指定方法的指定位置。
????????利用AOP可以對(duì)業(yè)務(wù)邏輯 的各個(gè)部分進(jìn)行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可重用性,同時(shí)提高 了開(kāi)發(fā)的效率。
如下圖所示: ????????把水平面抽象成一個(gè)切面對(duì)象,我們把日志代碼放到切面對(duì)象中,然后對(duì)這個(gè)切面對(duì)象去編程,本質(zhì)上還是面向?qū)ο缶幊?#xff0c;但是思想是面向切面編程。
通過(guò)aop可以對(duì)其進(jìn)行增強(qiáng),減少重復(fù)代碼,降低耦合?;诖韺?shí)現(xiàn)。
5個(gè)關(guān)鍵術(shù)語(yǔ)
1)橫切關(guān)注點(diǎn),從每個(gè)方法中抽取出來(lái)的同一類非核心業(yè)務(wù)
2)切面(Aspect),對(duì)橫切關(guān)注點(diǎn)進(jìn)行封裝的類,每個(gè)關(guān)注點(diǎn)體現(xiàn)為一個(gè)通知方法;通常使用 @Aspect 注解來(lái)定義切面。
3)通知(Advice),切面必須要完成的各個(gè)具體工作,比如我們的日志切面需要記錄接口調(diào)用前后的時(shí)長(zhǎng),就需要在調(diào)用接口前后記錄時(shí)間,再取差值。通知的方式有五種:
-
@Before:通知方法會(huì)在目標(biāo)方法調(diào)用之前執(zhí)行
-
@After:通知方法會(huì)在目標(biāo)方法調(diào)用后執(zhí)行
-
@AfterReturning:通知方法會(huì)在目標(biāo)方法返回后執(zhí)行
-
@AfterThrowing:通知方法會(huì)在目標(biāo)方法拋出異常后執(zhí)行
-
@Around:把整個(gè)目標(biāo)方法包裹起來(lái),在被調(diào)用前和調(diào)用之后分別執(zhí)行通知方法
4)連接點(diǎn)(JoinPoint),通知應(yīng)用的時(shí)機(jī),比如接口方法被調(diào)用時(shí)就是日志切面的連接點(diǎn)。
5)切點(diǎn)(Pointcut),通知功能被應(yīng)用的范圍,比如本篇日志切面的應(yīng)用范圍是所有 controller 的接口。通常使用 @Pointcut 注解來(lái)定義切點(diǎn)表達(dá)式。
項(xiàng)目中使用過(guò)AOP嗎?AOP使用場(chǎng)景?
我的項(xiàng)目里面,日志操作用過(guò)。
用戶請(qǐng)求的時(shí)候,我們需要記錄下這些操作,例如需要記錄操作的用戶是誰(shuí)、請(qǐng)求方式是什么、訪問(wèn)地址、模塊名稱、登錄IP、操作時(shí)間等。就用到了這個(gè)AOP。具體如何操作,看下面如何使用AOP。
常用的使用場(chǎng)景
-
記錄操作日志
-
緩存處理
-
Spring中內(nèi)置的事務(wù)
如何使用AOP?
例如日志操作:日志操作的核心是使用aop中的環(huán)繞通知+切點(diǎn)表達(dá)式(找到要記錄日志的方法),通過(guò)環(huán)繞通知的參數(shù)獲取請(qǐng)求方法的參數(shù),保存到數(shù)據(jù)庫(kù)。
日志用來(lái)記錄一下請(qǐng)求的方式(解析方法可以獲取)、URL、用戶名(解析Session可以獲取)、操作時(shí)間等。
????????1. 在項(xiàng)目中導(dǎo)入AOP,就是導(dǎo)入到xml文件中
????????2. 在切面類上加一個(gè)注解@Aspect
,表明這是切面類。例如日志操作,那你的切面類里面就需要寫(xiě)一些業(yè)務(wù):獲取操作時(shí)間、操作人的用戶名(可以用Session或token獲取)、訪問(wèn)的URL、請(qǐng)求方式等,然后將這些記錄到數(shù)據(jù)庫(kù)。
????????3. 自定義一個(gè)注解,用來(lái)標(biāo)注你要做的公共代碼。 ?
????????????????有的代碼需要記錄日志,有的不需要,那就用這個(gè)注解來(lái)表示哪些需要做日志。
AOP核心:動(dòng)態(tài)代理
????????將程序中的業(yè)務(wù)邏輯加到目標(biāo)類上,就會(huì)涉及到動(dòng)態(tài)代理,AOP的核心技術(shù)是動(dòng)態(tài)代理,體現(xiàn)動(dòng)態(tài)代理核心(mybatis的dao層其實(shí)就是使用到了jdk動(dòng)態(tài)代理,只有接口)需要通過(guò)CGlib生成實(shí)現(xiàn)類,作為模板類,給代理使用,Spring通過(guò)代理,引入模板類,生成代理類對(duì)象,invoke調(diào)用對(duì)象的Method方法,傳入目標(biāo)類對(duì)象和參數(shù),完成動(dòng)態(tài)代理
Spring AOP和 AspectJ AOP有什么區(qū)別?
-
springAOP 是spring支持的面向切面AOP 編程。
-
AspectJ是一個(gè)面向切面的框架,它擴(kuò)展了Java語(yǔ)言。AspectJ定義了AOP語(yǔ)法,它有一個(gè)專門(mén)的編譯器用來(lái)生成遵守Java字節(jié)編碼規(guī)范的Class文件。
springAOP 不是一個(gè)完備的AOP 方案。
AspectJ是最首創(chuàng)的AOP技術(shù),用來(lái)提供全面的AOP方案。
Spring AOP屬于運(yùn)行時(shí)增強(qiáng),而Aspect是編譯時(shí)增強(qiáng)。Spring AOP 基于代理(Proxying),而AspectJ基于字節(jié)碼操作(Bytecode Manipulation)。 Spring AOP已經(jīng)集成了Aspectl, Aspectl應(yīng)該算的上是Java生態(tài)系統(tǒng)中最完整的 AOP框架了。Aspectl相比于Spring AOP功能更加強(qiáng)大,但是 Spring AOP相對(duì)來(lái)說(shuō)更簡(jiǎn)單, 如果我們的切面比較少,那么兩者性能差異不大。但是,當(dāng)切面太多的話,最好選擇Aspectl,它比Spring A0P.快很多。 同級(jí)調(diào)用方法不可切入