AOP介紹
在軟件業(yè),AOP為Aspect Oriented Programming的縮寫(xiě),意為:面向切面編程,通過(guò)預(yù)編譯方式和運(yùn)行期動(dòng)態(tài)代理實(shí)現(xiàn)程序功能的統(tǒng)一維護(hù)的一種技術(shù)。AOP是OOP(面向?qū)ο缶幊蹋┑难永m(xù),是軟件開(kāi)發(fā)中的一個(gè)熱點(diǎn),也是Spring框架中的一個(gè)重要內(nèi)容,是函數(shù)式編程的一種衍生范型。利用AOP可以對(duì)業(yè)務(wù)邏輯的各個(gè)部分進(jìn)行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可重用性,同時(shí)提高了開(kāi)發(fā)的效率。
AOP采取橫向抽取機(jī)制,取代了傳統(tǒng)縱向繼承體系重復(fù)性代碼
經(jīng)典應(yīng)用:事務(wù)管理、性能監(jiān)視、安全檢查、緩存、日志等
Spring AOP使用純Java實(shí)現(xiàn),不需要專(zhuān)門(mén)的編譯過(guò)程和類(lèi)加載器,在運(yùn)行期通過(guò)代理方式向目標(biāo)類(lèi)織入增強(qiáng)代碼
AspectJ是一個(gè)基于Java語(yǔ)言的AOP框架,Spring2.0開(kāi)始,Spring AOP引入對(duì)Aspect的支持,AspectJ擴(kuò)展了Java語(yǔ)言,提供了一個(gè)專(zhuān)門(mén)的編譯器,在編譯時(shí)提供橫向代碼的織入
AOP實(shí)現(xiàn)原理
aop底層將采用代理機(jī)制進(jìn)行實(shí)現(xiàn)。
接口 + 實(shí)現(xiàn)類(lèi):spring采用 jdk 的動(dòng)態(tài)代理Proxy。
未實(shí)現(xiàn)接口的類(lèi):spring 采用 cglib字節(jié)碼增強(qiáng)。
AOP術(shù)語(yǔ)
1.target:目標(biāo)類(lèi),需要被代理的類(lèi)。例如:UserService
2.Joinpoint(連接點(diǎn)):所謂連接點(diǎn)是指那些可能被攔截到的方法。例如:所有的方法
3.PointCut 切入點(diǎn):已經(jīng)被增強(qiáng)的連接點(diǎn)。例如:addUser()
4.advice 通知/增強(qiáng),增強(qiáng)代碼。例如:after、before
5. Weaving(織入):是指把增強(qiáng)advice應(yīng)用到目標(biāo)對(duì)象target來(lái)創(chuàng)建新的代理對(duì)象proxy的過(guò)程.
6.proxy 代理類(lèi)
7. Aspect(切面): 是切入點(diǎn)pointcut和通知advice的結(jié)合
?????? 一個(gè)線(xiàn)是一個(gè)特殊的面。
?????? 一個(gè)切入點(diǎn)和一個(gè)通知,組成成一個(gè)特殊的面。
AOP聯(lián)盟通知類(lèi)型
AOP聯(lián)盟為通知Advice定義了org.aopalliance.aop.Advice
Spring按照通知Advice在目標(biāo)類(lèi)方法的連接點(diǎn)位置,可以分為5類(lèi)
前置通知org.springframework.aop.MethodBeforeAdvice
在目標(biāo)方法執(zhí)行前實(shí)施增強(qiáng)
后置通知 org.springframework.aop.AfterReturningAdvice
在目標(biāo)方法執(zhí)行后實(shí)施增強(qiáng)
環(huán)繞通知 org.aopalliance.intercept.MethodInterceptor
在目標(biāo)方法執(zhí)行前后實(shí)施增強(qiáng)
異常拋出通知 org.springframework.aop.ThrowsAdvice
在方法拋出異常后實(shí)施增強(qiáng)
引介通知org.springframework.aop.IntroductionInterceptor
在目標(biāo)類(lèi)中添加一些新的方法和屬性
springAOP編程:全自動(dòng)

如果用上圖所示的配置實(shí)現(xiàn)aop,那么切面類(lèi)就需要實(shí)現(xiàn)特定的接口,這是為了表明該切面類(lèi)要的切入點(diǎn)是在方法的前面還是后面或者環(huán)繞等,例:

AspectJ
介紹
AspectJ是一個(gè)基于Java語(yǔ)言的AOP框架
Spring2.0以后新增了對(duì)AspectJ切點(diǎn)表達(dá)式支持
@AspectJ 是AspectJ1.5新增功能,通過(guò)JDK5注解技術(shù),允許直接在Bean類(lèi)中定義切面
新版本Spring框架,建議使用AspectJ方式來(lái)開(kāi)發(fā)AOP
主要用途:自定義開(kāi)發(fā)
切入點(diǎn)表達(dá)式
execution()?用于描述方法,例,execution(*com.itheima.crm.*.service..*.*(..))
AspectJ 通知類(lèi)型
個(gè)數(shù):6種,知道5種,掌握1中。
?????? before:前置通知(應(yīng)用:各種校驗(yàn))
????????????? 在方法執(zhí)行前執(zhí)行,如果通知拋出異常,阻止方法運(yùn)行
?????? afterReturning:后置通知(應(yīng)用:常規(guī)數(shù)據(jù)處理)
????????????? 方法正常返回后執(zhí)行,如果方法中拋出異常,通知無(wú)法執(zhí)行
????????????? 必須在方法執(zhí)行后才執(zhí)行,所以可以獲得方法的返回值。
?????? around:環(huán)繞通知(應(yīng)用:十分強(qiáng)大,可以做任何事情)
????????????? 方法執(zhí)行前后分別執(zhí)行,可以阻止方法的執(zhí)行
????????????? 必須手動(dòng)執(zhí)行目標(biāo)方法
?????? afterThrowing:拋出異常通知(應(yīng)用:包裝異常信息)
????????????? 方法拋出異常后執(zhí)行,如果方法沒(méi)有拋出異常,無(wú)法執(zhí)行
?????? after:最終通知(應(yīng)用:清理現(xiàn)場(chǎng))
????????????? 方法執(zhí)行完畢后執(zhí)行,無(wú)論方法中是否出現(xiàn)異常
AspectJ基于xml的使用
配置如下

對(duì)比于上面的springAOP編程,可以發(fā)現(xiàn),在配置上的區(qū)別是,aspectj的配置中聲明了切面類(lèi)的某個(gè)方法要被用于什么時(shí)機(jī),例如? aop:before,而springAOP編程中則沒(méi)有聲明這一點(diǎn),它實(shí)現(xiàn)這一效果是通過(guò)讓切面類(lèi)去是實(shí)現(xiàn)特定的接口。
aspectj中的切面類(lèi)不需要實(shí)現(xiàn)特定的接口,所以他們可以隨意定義方法,這樣就顯得更加自由,并且aspectj的配置能夠確定到切面類(lèi)中的某個(gè)方法,這樣我們就可以在一個(gè)切面類(lèi)中定義多個(gè)方法,而每個(gè)方法都可用于不同的切入時(shí)機(jī),例如,一個(gè)方法用于before,一個(gè)方法用于after-Returning。
至于springAOP編程能不能實(shí)現(xiàn)該效果,我沒(méi)有去實(shí)驗(yàn),但是估計(jì)是可以的,因?yàn)槲覀兛梢酝ㄟ^(guò)實(shí)現(xiàn)多個(gè)特定的接口,也就是在同一個(gè)切面類(lèi)中實(shí)現(xiàn)好幾個(gè)特定的方法,多種時(shí)機(jī)下復(fù)用這個(gè)切面類(lèi),應(yīng)該也可以達(dá)到該效果。
下面是切面類(lèi)中各方法參數(shù)與xml配置的統(tǒng)一


AspectJ基于注解的使用
替換bean

替換aop

替換通知


aop注解總結(jié)
@Aspect?聲明切面,修飾切面類(lèi),從而獲得通知。
通知
?????? @Before前置
?????? @AfterReturning后置
?????? @Around環(huán)繞
?????? @AfterThrowing拋出異常
?????? @After最終
切入點(diǎn)
?????? @PointCut,修飾方法private void xxx(){}?之后通過(guò)“方法名”獲得切入點(diǎn)引用