AOP的應(yīng)用場景
1、日志記錄
2财破、權(quán)限驗(yàn)證
3掰派、效率檢查(個(gè)人在代碼上,喜歡用注解 + 切面左痢,實(shí)現(xiàn)校驗(yàn)靡羡,redis分布式鎖等功能)
4、事務(wù)管理(spring 的事務(wù)就是用AOP實(shí)現(xiàn)的)
spring AOP 和 AspectJ的關(guān)系
兩者都是為了實(shí)現(xiàn)AOP這個(gè)目的俊性,而出現(xiàn)的技術(shù)略步,spring aop 參考 AspectJ編程風(fēng)格,在基于Spring AOP編程的過程中磅废,基于AspectJ框架標(biāo)準(zhǔn)纳像,spring中定義了五種類型的通知荆烈,它們分別是:
- 前置通知 (@Before)
- 返回通知 (@AfterReturning)
- 異常通知 (@AfterThrowing)
- 后置通知 (@After)
- 環(huán)繞通知 (@Around) :(優(yōu)先級最高)
簡述一下Spring AOP的設(shè)計(jì)原理
代理的創(chuàng)建
創(chuàng)建代理工廠:攔截器數(shù)組拯勉,目標(biāo)對象接口數(shù)組,目標(biāo)對象憔购。
創(chuàng)建代理工廠時(shí)宫峦,默認(rèn)會在攔截器數(shù)組尾部再增加一個(gè)默認(rèn)攔截器 — 用于最終的調(diào)用目標(biāo)方法。
當(dāng)調(diào)用 getProxy 方法的時(shí)候玫鸟,會根據(jù)接口數(shù)量大余 0 條件返回一個(gè)代理對象(JDK or Cglib)导绷。
注意:創(chuàng)建代理對象時(shí),同時(shí)會創(chuàng)建一個(gè)外層攔截器屎飘,這個(gè)攔截器就是 Spring 內(nèi)核的攔截器妥曲,用于控制整個(gè) AOP 的流程贾费。
代理的調(diào)用
當(dāng)對代理對象進(jìn)行調(diào)用時(shí),就會觸發(fā)外層攔截器檐盟。
外層攔截器根據(jù)代理配置信息褂萧,創(chuàng)建內(nèi)層攔截器鏈。創(chuàng)建的過程中葵萎,會根據(jù)表達(dá)式判斷當(dāng)前攔截是否匹配這個(gè)攔截器导犹。而這個(gè)攔截器鏈設(shè)計(jì)模式就是職責(zé)鏈模式。
當(dāng)整個(gè)鏈條執(zhí)行到最后時(shí)羡忘,就會觸發(fā)創(chuàng)建代理時(shí)那個(gè)尾部的默認(rèn)攔截器谎痢,從而調(diào)用目標(biāo)方法,最后返回卷雕。
什么時(shí)候Spring Aop會失效
- 要增強(qiáng)的類或方法沒被spring管理
- 要被增強(qiáng)的類或方法同時(shí)被spring和springMVC掃描节猿,spring mvc的xml中重復(fù)掃描了
- 用的注解方式?jīng)]有開啟注解支持
- 在一個(gè)類內(nèi)部調(diào)用時(shí),被調(diào)用方法的 AOP 聲明將不起作用
- 對于基于接口動態(tài)代理的 AOP 事務(wù)增強(qiáng)來說漫雕,由于接口的方法都必然是
public
這就要求實(shí)現(xiàn)類的實(shí)現(xiàn)方法也必須是public
的(不能是protected沐批、private
等),同時(shí)不能使用static
的修飾符蝎亚。 - 基于CGLib 字節(jié)碼動態(tài)代理的方案是通過擴(kuò)展被增強(qiáng)類九孩,動態(tài)創(chuàng)建其子類的方式進(jìn)行 AOP 增強(qiáng)植入的,由于使用
final发框、static躺彬、private
修飾符的方法都不能被子類覆蓋,這些方法將無法實(shí)施 AOP 增強(qiáng)梅惯。
文章參考自:
是什么導(dǎo)致了Spring Aop失效了宪拥?
AOP失效了...分析
Spring AOP有哪些通知類型,它們的執(zhí)行順序是怎樣的铣减?