溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Spring AOP應(yīng)用場(chǎng)景你還不知道?這篇一定要看!

發(fā)布時(shí)間:2020-06-27 15:23:58 來(lái)源:網(wǎng)絡(luò) 閱讀:459 作者:架構(gòu)師追風(fēng) 欄目:編程語(yǔ)言

回顧一下Spring AOP的知識(shí)

為什么會(huì)有面向切面編程(AOP)?

我們知道Java是一個(gè)面向?qū)ο螅∣OP)的語(yǔ)言,但它有一些弊端,比如當(dāng)我們需要為多個(gè)不具有繼承關(guān)系的對(duì)象引入一個(gè)公共行為,例如日志、權(quán)限驗(yàn)證、事務(wù)等功能時(shí),只能在在每個(gè)對(duì)象里引用公共行為。這樣做不便于維護(hù),而且有大量重復(fù)代碼。AOP的出現(xiàn)彌補(bǔ)了OOP的這點(diǎn)不足。

Spring AOP 中設(shè)計(jì)的一些核心知識(shí),面試問(wèn)題?

1、能說(shuō)一下Spring AOP用的是哪種設(shè)計(jì)模式?

回答:代理模式。


2、 能簡(jiǎn)單聊一下你對(duì)代理模式的理解嗎?

代理模式 balabala......,記住一些貼近日常的示例方便理解,如買(mǎi)火車(chē)票,Windows 里面的快捷方式...


3、 知道JDK代理和Cglib代理有什么區(qū)別?

我們不需要?jiǎng)?chuàng)建代理類,JDK 在運(yùn)行時(shí)為我們動(dòng)態(tài)的來(lái)創(chuàng)建,JDK代理是接口 balabala

若目標(biāo)類不存在接口,則使用Cglib生成代理,balabala

不管是JDK代理還是Cglib代理本質(zhì)上都是對(duì)字節(jié)碼進(jìn)行操作,balabala


4、讓你實(shí)現(xiàn)一個(gè)JDK實(shí)現(xiàn)動(dòng)態(tài)代理?你的思路是什么?

照葫蘆畫(huà)瓢,照貓畫(huà)虎。

Proxy: 定義一個(gè)自己的Proxy類

InvocationHandler:定義一個(gè)自己的InvocationHandler類

ClassLoad:自定義類加載器(方便加載我們自己指定的路徑下面的類)


上面簡(jiǎn)單回顧,并拋出一些問(wèn)題。帶著問(wèn)題閱讀,效果杠杠的。

Spring AOP應(yīng)用場(chǎng)景你還不知道?這篇一定要看!

回到本文的重點(diǎn)

SpringAOP的在實(shí)際應(yīng)用中場(chǎng)景有哪些?

  1. Authentication 權(quán)限

  2. Caching 緩存

  3. Context passing 內(nèi)容傳遞

  4. Error handling 錯(cuò)誤處理

  5. Lazy loading 懶加載

  6. Debugging 調(diào)試

  7. logging,tracing,profiling and monitoring 記錄跟蹤 優(yōu)化 校準(zhǔn)

  8. Performance optimization 性能優(yōu)化

  9. Persistence 持久化

  10. Resource pooling 資源池

  11. Synchronization 同步

  12. Transactions 事務(wù)

  13. Logging 日志


以日志為例

假如沒(méi)有aop,在做日志處理的時(shí)候,我們會(huì)在每個(gè)方法中添加日志處理,比如

Spring AOP應(yīng)用場(chǎng)景你還不知道?這篇一定要看!


但大多數(shù)的日子處理代碼是相同的,為了實(shí)現(xiàn)代碼復(fù)用,我們可能把日志處理抽離成一個(gè)新的方法。但是這樣我們?nèi)匀槐仨毷謩?dòng)插入這些方法。

Spring AOP應(yīng)用場(chǎng)景你還不知道?這篇一定要看!

但這樣兩個(gè)方法就是強(qiáng)耦合的,假如此時(shí)我們不需要這個(gè)功能了,或者想換成其他功能,那么就必須一個(gè)個(gè)修改。

通過(guò)動(dòng)態(tài)代理,可以在指定位置執(zhí)行對(duì)應(yīng)流程。這樣就可以將一些橫向的功能抽離出來(lái)形成一個(gè)獨(dú)立的模塊,然后在指定位置

插入這些功能。這樣的思想,被稱為面向切面編程,亦即AOP。

Spring AOP應(yīng)用場(chǎng)景你還不知道?這篇一定要看!

為了在指定位置執(zhí)行這些橫向的功能,需要知道指定的是什么地方。

Spring AOP應(yīng)用場(chǎng)景你還不知道?這篇一定要看!

例如上圖,方法級(jí)別的aop實(shí)現(xiàn),在一個(gè)程序執(zhí)行鏈條中,把method2稱為切點(diǎn),也就是說(shuō)在method2執(zhí)行時(shí)會(huì)執(zhí)行橫切的功能,那么是在method2之前還是之后呢,又是執(zhí)行什么呢?這些都由advice(通知)來(lái)指定。advice有5種類型,分別是:

  • Before(前置通知) 目標(biāo)方法調(diào)用之前執(zhí)行

  • After(后置通知) 目標(biāo)方法調(diào)用之后執(zhí)行

  • After-returning(返回通知) 目標(biāo)方法執(zhí)行成功后執(zhí)行

  • After-throwing(異常通知) 目標(biāo)方法拋出異常后執(zhí)行

  • Around(環(huán)繞通知) 相當(dāng)于合并了前置和后置

把切點(diǎn)和通知合在一起就是切面了,一個(gè)切面指定了在何時(shí)何地執(zhí)行何種方法。在spring aop中如此定義這個(gè)切面:

@Aspect
@Component
public?class?HelloAspect?{

??@Before("execution(*?com.test.service.impl.HelloServiceImpl.sayHello(..))")
??public?void?sayHello(){
????System.out.println("hello?Java編程技術(shù)樂(lè)園!");
??}

}

使用注解@Aspect將某個(gè)特定的類聲明為切面,這樣,該類下的方法就可以聲明為橫向的功能點(diǎn)后插入到指定位置。使用execution表達(dá)式聲明在這個(gè)切點(diǎn),格式如下:

Spring AOP應(yīng)用場(chǎng)景你還不知道?這篇一定要看!

第一個(gè)位置指定了方法的返回值,*號(hào)代表任意類型的返回值,然后是所在的類和方法名,星號(hào)同樣代表任意,就是該類中任意的方法,在上一個(gè)例子中方法名是sayHello,則是指定了該類中的sayHello方法。然后最后一個(gè)參數(shù)是方法入?yún)?,因?yàn)镴ava中支持重載,所以這個(gè)參數(shù)可以幫助你更精確的進(jìn)行定位。兩點(diǎn)表示任意參數(shù)類型。這樣,execution表達(dá)式告訴了程序該在何地執(zhí)行通知。而被諸如@Before注解修飾的方法就是通知的內(nèi)容,也就是做什么。

總結(jié)

我們使用spring aop,有兩點(diǎn)需要注意:

1、將切面類聲明為一個(gè)bean

2、切點(diǎn)指定的方法所在的類也同樣需由spring注入才能生效
歡迎大家關(guān)注我的公種浩【程序員追風(fēng)】,文章都會(huì)在里面更新,整理的資料也會(huì)放在里面。

最后歡迎大家一起交流,喜歡文章記得點(diǎn)個(gè)贊喲,感謝支持!



向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI