AOP應(yīng)用以及原理

0. AOP是什么?

AOP,面向切面編程,是對OOP的補(bǔ)充。面向切面編程有好幾種方式,可以在編譯時(shí)候織入,也可以在運(yùn)行時(shí)候織入,將代碼切入到指定的方法或者位置上去。一般來說有以下幾種方式:

AspectJ編譯時(shí)增強(qiáng)

aspectj編譯時(shí)增強(qiáng),既是靜態(tài)代理增強(qiáng),也就是會在編譯階段生成代理,將代碼織入到Java的字節(jié)碼中去。

Spring AOP的運(yùn)行時(shí)增強(qiáng)

Spring AOP是基于代理機(jī)制的,并且Spring AOP使用的是動態(tài)代理增強(qiáng),動態(tài)代理不會改變類的字節(jié)碼,而是動態(tài)的生成代理對象。Spring AOP的動態(tài)代理機(jī)制有兩種方式:JDK動態(tài)代理和CGLIB動態(tài)代理。

JDK動態(tài)代理

JDK動態(tài)代理需要被代理的類必須實(shí)現(xiàn)一個(gè)接口,通過使用反射來接受被代理的類。

CGLIB動態(tài)代理

CGLIB動態(tài)代理可以不用需要被代理類必須實(shí)現(xiàn)接口,被代理類可以是一個(gè)類。

Spring AOP

上面說到了Spring AOP中使用的是動態(tài)代理機(jī)制,同時(shí)也分為兩種代理機(jī)制:JDK動態(tài)代理和CGLIB動態(tài)代理,這可以在源碼中看到,在DefaultAopProxyFactory的createAopProxy中可看到:

public AopProxy createAopProxy(AdvisedSupport advisedSupport) throws AopConfigException {
    //可以看到這里有條件是沒有實(shí)現(xiàn)接口
    boolean useCglib = advisedSupport.getOptimize() 
                                    || advisedSupport.getProxyTargetClass() 
                                    || advisedSupport.getProxiedInterfaces().length == 0;
    if (useCglib) {
        return CglibProxyFactory.createCglibProxy(advisedSupport);
    }
    else {
        // Depends on whether we have expose proxy or frozen or static ts
        return new JdkDynamicAopProxy(advisedSupport);
    }
}

對于接口的代理使用的JDK動態(tài)代理,而對于類的代理使用的是CGLIB動態(tài)代理。
AOP的相關(guān)概念

1. AOP的相關(guān)概念

  • Aspect,切面,一個(gè)關(guān)注點(diǎn)的模塊化,這個(gè)關(guān)注點(diǎn)可能會橫切多個(gè)對象。
  • JoinPoint(連接點(diǎn)),程序中可能作為代碼注入目標(biāo)的特定的點(diǎn)。在AspectJ中可以作為JoinPoints的地方包括:
JoinPoints 說明 示例
method call 函數(shù)調(diào)用 比如調(diào)用Log.e(),這是一處Joint point
method execution 函數(shù)執(zhí)行 比如Log.e()的執(zhí)行內(nèi)部,是一處Joint Point
constructor call 構(gòu)造函數(shù)調(diào)用 與方法的調(diào)用類型
constructor executor 構(gòu)造函數(shù)執(zhí)行 與方法的執(zhí)行執(zhí)行
field get 獲取某個(gè)變量
field set 設(shè)置某個(gè)變量
static initialization 類初始化
initialization object在構(gòu)造函數(shù)中做的一些工作
handler 異常處理 對應(yīng)try-catch()中,對應(yīng)的catch塊內(nèi)的執(zhí)行
  • Advice,通知類型,在切面的某個(gè)特定的連接點(diǎn)上執(zhí)行的動作。其實(shí)就是注入到class文件中的代碼片。典型的 Advice 類型有 before、after 和 around,分別表示在目標(biāo)方法執(zhí)行之前、執(zhí)行后和完全替代目標(biāo)方法執(zhí)行的代碼:
    前置通知(Before advice):在某連接點(diǎn)之前執(zhí)行的通知,但這個(gè)通知不能阻止連接點(diǎn)之前的執(zhí)行流程(除非它拋出一個(gè)異常)。
    后置通知(After returning advice):在某連接點(diǎn)正常完成后執(zhí)行的通知:例如,一個(gè)方法沒有拋出任何異常,正常返回。
    異常通知(After throwing advice):在方法拋出異常退出時(shí)執(zhí)行的通知。
    最終通知(After (finally) advice):當(dāng)某連接點(diǎn)退出的時(shí)候執(zhí)行的通知(不論是正常返回還是異常退出)。
    環(huán)繞通知(Around Advice):包圍一個(gè)連接點(diǎn)的通知,如方法調(diào)用。這是最強(qiáng)大的一種通知類型。環(huán)繞通知可以在方法調(diào)用前后完成自定義的行為。它也會選擇是否繼續(xù)執(zhí)行連接點(diǎn)或直接返回它自己的返回值或拋出異常來結(jié)束執(zhí)行。

  • Pointcut,切點(diǎn),匹配連接點(diǎn)的斷言。通知和一個(gè)切入點(diǎn)表達(dá)式關(guān)聯(lián),并在滿足這個(gè)切入點(diǎn)的連接點(diǎn)上運(yùn)行(例如,當(dāng)執(zhí)行某個(gè)特定名稱的方法時(shí))。

  • Weaving,注入代碼(advices)到目標(biāo)位置(joint points)的過程

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

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

  • 心情沒法不沉重,被問到AOP是什么?AOP原理是什么?我竟然張大了嘴巴,說不出來!對于一個(gè)程序員的打擊,還能有比這...
    加大裝益達(dá)閱讀 2,411評論 0 2
  • 概述 Spring是什么? Spring是一個(gè)開源框架,為了解決企業(yè)應(yīng)用開發(fā)的復(fù)雜性而創(chuàng)建的,但是現(xiàn)在已經(jīng)不止于企...
    瑯筑閱讀 1,294評論 2 8
  • 第五章 Spring AOP 概覽 本章首先是脫離Spring之外講了AOP的基礎(chǔ),其次分析了AOP的兩種類型:...
    劉凝云閱讀 1,141評論 0 0
  • 前言 只有光頭才能變強(qiáng) 上一篇已經(jīng)講解了Spring IOC知識點(diǎn)一網(wǎng)打盡!,這篇主要是講解Spring的AOP模...
    Java3y閱讀 7,021評論 8 181
  • 浪花打濕了月光 月光卻挽不回流去的情 思念化作了寸草 在大地上叢生 風(fēng)拂過你的發(fā)髻 發(fā)髻卻纏綿了我的思緒 依風(fēng)飄離...
    鈍石閱讀 93評論 0 0

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