Spring AOP思維導(dǎo)圖

轉(zhuǎn)載https://my.oschina.net/u/3080373/blog/1503693

什么是AOP

AOP(Aspect-OrientedProgramming,面向方面編程),可以說(shuō)是OOP(Object-Oriented Programing,面向?qū)ο缶幊蹋┑难a(bǔ)充和完善。OOP允許你定義從上到下的關(guān)系,但并不適合定義從左到右的關(guān)系。例如日志功能。日志代碼往往水平地散布在所有對(duì)象層次中,而與它所散布到的對(duì)象的核心功能毫無(wú)關(guān)系。這種散布在各處的無(wú)關(guān)的代碼被稱為橫切(cross-cutting)代碼,在OOP設(shè)計(jì)中,它導(dǎo)致了大量代碼的重復(fù),而不利于各個(gè)模塊的重用。

而AOP技術(shù)則恰恰相反,它利用一種稱為“橫切”的技術(shù),剖解開(kāi)封裝的對(duì)象內(nèi)部,并將那些影響了多個(gè)類的公共行為封裝到一個(gè)可重用模塊,并將其名為“Aspect”,即方面。所謂“方面”,簡(jiǎn)單地說(shuō),就是將那些與業(yè)務(wù)無(wú)關(guān),卻為業(yè)務(wù)模塊所共同調(diào)用的邏輯或責(zé)任封裝起來(lái),便于減少系統(tǒng)的重復(fù)代碼,降低模塊間的耦合度,并有利于未來(lái)的可操作性和可維護(hù)性。

aop使用場(chǎng)景

aop框架種類

  • AspectJ
  • JBoss AOP
  • Spring AOP

使用aop可以做的事情有很多。

  • 性能監(jiān)控,在方法調(diào)用前后記錄調(diào)用時(shí)間,方法執(zhí)行太長(zhǎng)或超時(shí)報(bào)警。
  • 緩存代理,緩存某方法的返回值,下次執(zhí)行該方法時(shí),直接從緩存里獲取。
  • 軟件破解,使用AOP修改軟件的驗(yàn)證類的判斷邏輯。
  • 記錄日志,在方法執(zhí)行前后記錄系統(tǒng)日志。
  • 工作流系統(tǒng),工作流系統(tǒng)需要將業(yè)務(wù)代碼和流程引擎代碼混合在一起執(zhí)行,那么我們可以使用AOP將其分離,并動(dòng)態(tài)掛接業(yè)務(wù)。
  • 權(quán)限驗(yàn)證,方法執(zhí)行前驗(yàn)證是否有權(quán)限執(zhí)行當(dāng)前方法,沒(méi)有則拋出沒(méi)有權(quán)限執(zhí)行異常,由業(yè)務(wù)代碼捕捉。

觀察一下傳統(tǒng)編碼方式與使用aop的區(qū)別

核心概念

描述AOP常用的一些術(shù)語(yǔ)有通知(Adivce)、切點(diǎn)(Pointcut)、連接點(diǎn)(Join point)、切面(Aspect)、引入(Introduction)、織入(Weaving)、通知(Advice)等。

簡(jiǎn)單例子

相比xml配置,基于注解的方式更加簡(jiǎn)潔方便。

@Aspect
public class TransactionDemo {
    
    @Pointcut(value="execution(* com.yangxin.core.service.*.*.*(..))")
    public void point(){
        
    }
    
    @Before(value="point()")
    public void before(){
        System.out.println("transaction begin");
    }
    
    @AfterReturning(value = "point()")
    public void after(){
        System.out.println("transaction commit");
    }
    
    @Around("point()")
    public void around(ProceedingJoinPoint joinPoint) throws Throwable{
        System.out.println("transaction begin");
        joinPoint.proceed();
        System.out.println("transaction commit");
    }
}

在applicationContext.xml中配置。

<aop:aspectj-autoproxy />
<bean id = "transactionDemo" class = "com.yangxin.core.transaction.TransactionDemo" />

spring aop原理

通過(guò)前面介紹可以知道:AOP 代理其實(shí)是由 AOP 框架動(dòng)態(tài)生成的一個(gè)對(duì)象,該對(duì)象可作為目標(biāo)對(duì)象使用。AOP 代理包含了目標(biāo)對(duì)象的全部方法,但 AOP 代理中的方法與目標(biāo)對(duì)象的方法存在差異:AOP 方法在特定切入點(diǎn)添加了增強(qiáng)處理,并回調(diào)了目標(biāo)對(duì)象的方法。

Spring 的 AOP 代理由 Spring 的 IoC 容器負(fù)責(zé)生成、管理,其依賴關(guān)系也由 IoC 容器負(fù)責(zé)管理。因此,AOP 代理可以直接使用容器中的其他 Bean 實(shí)例作為目標(biāo),這種關(guān)系可由 IoC 容器的依賴注入提供。

aop開(kāi)發(fā)時(shí),其中需要程序員參與的只有 3 個(gè)部分:

  • 定義普通業(yè)務(wù)組件。
  • 定義切入點(diǎn),一個(gè)切入點(diǎn)可能橫切多個(gè)業(yè)務(wù)組件。
  • 定義增強(qiáng)處理,增強(qiáng)處理就是在 AOP 框架為普通業(yè)務(wù)組件織入的處理動(dòng)作。

為了理清關(guān)系,先來(lái)個(gè)類關(guān)系圖。

兩種動(dòng)態(tài)代理方式

Spring默認(rèn)采取的動(dòng)態(tài)代理機(jī)制實(shí)現(xiàn)AOP,當(dāng)動(dòng)態(tài)代理不可用時(shí)(代理類無(wú)接口)會(huì)使用CGlib機(jī)制。

Spring提供了兩種方式來(lái)生成代理對(duì)象: JDKProxy和Cglib,具體使用哪種方式生成由AopProxyFactory根據(jù)AdvisedSupport對(duì)象的配置來(lái)決定。默認(rèn)的策略是如果目標(biāo)類是接口,則使用JDK動(dòng)態(tài)代理技術(shù),否則使用Cglib來(lái)生成代理。

JDK動(dòng)態(tài)代理

  • JDK動(dòng)態(tài)代理主要涉及到j(luò)ava.lang.reflect包中的兩個(gè)類:Proxy和InvocationHandler。InvocationHandler是一個(gè)接口,通過(guò)實(shí)現(xiàn)該接口定義橫切邏輯,并通過(guò)反射機(jī)制調(diào)用目標(biāo)類的代碼,動(dòng)態(tài)將橫切邏輯和業(yè)務(wù)邏輯編制在一起。
  • Proxy利用InvocationHandler動(dòng)態(tài)創(chuàng)建一個(gè)符合某一接口的實(shí)例,生成目標(biāo)類的代理對(duì)象。

CGLib動(dòng)態(tài)代理

  • CGLib全稱為Code Generation Library,是一個(gè)強(qiáng)大的高性能,高質(zhì)量的代碼生成類庫(kù),可以在運(yùn)行期擴(kuò)展Java類與實(shí)現(xiàn)Java接口,CGLib封裝了asm,可以再運(yùn)行期動(dòng)態(tài)生成新的class。和JDK動(dòng)態(tài)代理相比較:JDK創(chuàng)建代理有一個(gè)限制,就是只能為接口創(chuàng)建代理實(shí)例,而對(duì)于沒(méi)有通過(guò)接口定義業(yè)務(wù)方法的類,則可以通過(guò)CGLib創(chuàng)建動(dòng)態(tài)代理。

知識(shí)拓展

通過(guò)上面的分析,大家是否有種熟悉的感覺(jué),似乎和攔截器、過(guò)濾器的功能相似。那么問(wèn)題來(lái)了,aop與攔截器、過(guò)濾器是什么關(guān)系。

先來(lái)回顧一下攔截器與過(guò)濾器。如下圖一網(wǎng)友的測(cè)試,在web.xml中注冊(cè)了TestFilter1和TestFilter2。然后在spring的配置文件中配置了BaseInterceptor和TestInterceptor。得到的結(jié)果如下圖所示。從圖中可以看出,攔截器和過(guò)濾器都橫切了業(yè)務(wù)方法,看似符合aop的思想。

Filter過(guò)濾器:攔截web訪問(wèn)url地址。 Interceptor攔截器:攔截以 .action結(jié)尾的url,攔截Action的訪問(wèn)。 Spring AOP攔截器:只能攔截Spring管理Bean的訪問(wèn)(業(yè)務(wù)層Service)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,562評(píng)論 19 139
  • 世事洞明皆學(xué)問(wèn),人情練達(dá)即文章。 然而,有一種真誠(chéng),是不諳世事。 它并不耀眼甚至略顯愚鈍。 我愿保持本真。 素人罷。
    Y_9ac2閱讀 134評(píng)論 0 0
  • 人生結(jié)構(gòu)一直在改變, 就算旅行的意義不變, 但方式一定會(huì)改變。 得知我又出門浪,照舊會(huì)有朋友日常催攻略。 是的,僅...
    一加雨錄閱讀 302評(píng)論 0 0
  • 少年與貓的故事, 請(qǐng)你來(lái),我講給你聽(tīng)啊。 (二) 貓 又有一波無(wú)聊的人類進(jìn)來(lái)了。。。 我懶懶的舔著自己的尾巴尖兒,...
    易長(zhǎng)生閱讀 275評(píng)論 2 1

友情鏈接更多精彩內(nèi)容