spring詳解(八)「AOP」

4.Spring的AOP:

AspectJ

Aspectj是什么?

官方網(wǎng)站的的介紹是這樣的:
<li>a seamless aspect-oriented extension to the Javatm programming language(一種基于Java平臺的面向切面編程的語言)
<li>Java platform compatible(兼容Java平臺慢睡,可以無縫擴(kuò)展)
<li>easy to learn and use(易學(xué)易用)

Aspectj能做什么?

clean modularization of crosscutting concerns, such as error checking and handling, synchronization, context-sensitive behavior, performance optimizations, monitoring and logging, debugging support, and multi-object protocols烫葬。
大意是說:干凈的模塊化橫切關(guān)注點(diǎn)(也就是說單純杨蛋,基本上無侵入),如錯(cuò)誤檢查和處理,同步哩照,上下文敏感的行為蓄髓,性能優(yōu)化贡未,監(jiān)控和記錄汹族,調(diào)試支持讼昆,多目標(biāo)的協(xié)議托享。

還有那些常用的Aop,以及他們的區(qū)別

<li>boss Aop:我基本上沒有用過,所以沒有發(fā)言權(quán).
<li>Spring Aop:Spring自己原生的Aop闰围,只能用一個(gè)詞來形容:難用赃绊。 你需要實(shí)現(xiàn)大量的接口羡榴,繼承大量的類碧查,所以spring aop一度被千夫所指。這于他的無侵入校仑,低耦合完全沖突忠售。不過Spring對開源的優(yōu)秀框架,組建向來是采用兼容迄沫,并入的態(tài)度稻扬。所以,后來的Spring 就提供了Aspectj支持羊瘩,也就是我們后來所說的基于純POJO的Aop泰佳。

區(qū)別:springAop采用的動態(tài)織入,而Aspectj是靜態(tài)織入尘吗。靜態(tài)織入:指在編譯時(shí)期就織入逝她,即:編譯出來的class文件,字節(jié)碼就已經(jīng)被織入了摇予。動態(tài)織入又分靜動兩種汽绢,靜則指織入過程只在第一次調(diào)用時(shí)執(zhí)行吗跋;動則指根據(jù)代碼動態(tài)運(yùn)行的中間狀態(tài)來決定如何操作侧戴,每次調(diào)用Target的時(shí)候都執(zhí)行。有不清楚的同學(xué)跌宛,可以自己補(bǔ)下基礎(chǔ)的代理知識酗宋。

AOP的基本概念

AOP框架不與特定的代碼耦合.下面是一些面向切面編程的術(shù)語:

切面(Aspect):業(yè)務(wù)流程運(yùn)行到某個(gè)特定的步驟,也就是一個(gè)應(yīng)用運(yùn)行的關(guān)注點(diǎn)疆拘,關(guān)注點(diǎn)可能橫切多個(gè)對象蜕猫,所以常常也被稱為橫切關(guān)注點(diǎn)。

連接點(diǎn)(Joinpoint):程序執(zhí)行過程明確的點(diǎn)哎迄,如方法的調(diào)用回右、異常的拋出,Spring AOP中連接點(diǎn)總是方法的調(diào)用漱挚。

增強(qiáng)處理(Advice):AOP框架在特定的切入點(diǎn)執(zhí)行的增強(qiáng)處理翔烁,處理有around、before和After等類型旨涝。

切入點(diǎn)(Pointcut):可以插入增強(qiáng)處理的連接點(diǎn)蹬屹,簡而言之,當(dāng)某個(gè)連接點(diǎn)滿足指定要求時(shí),該連接點(diǎn)將被添加增強(qiáng)處理慨默,該連接點(diǎn)也就變成了切入點(diǎn).

例如一下代碼:

pointcut xxxPointcut(){
    :execution(void H*.say*());
}

每個(gè)方法的調(diào)用都只是連接點(diǎn)贩耐,但如果該方法屬于H開頭的類,且方法名以say開頭厦取,按照方法的執(zhí)行將變成切入點(diǎn)潮太。

引入:將方法添加到被處理的類中,Spring允許引入新的接口到任何被處理的對象蒜胖。例如:你可以使用一個(gè)引用消别,使任何對象實(shí)現(xiàn)IsModified接口,以此簡化緩存台谢。

目標(biāo)對象:被AOP增強(qiáng)處理的對象寻狂,也被稱為被增強(qiáng)的對象,如果AOP框架是通過運(yùn)行時(shí)代理來實(shí)現(xiàn)的朋沮,那么這個(gè)對象將是一個(gè)被代理的對象蛇券。

AOP代理:AOP框架創(chuàng)建的 對象,簡單的說樊拓,代理就是對目標(biāo)對象的加強(qiáng)纠亚,Spring的AOP代理可以使JDK動態(tài)代理,也可以是CGLIB代理筋夏,前者為實(shí)現(xiàn)接口的目標(biāo)對象的代理后者為不實(shí)現(xiàn)接口的目標(biāo)對象的代理蒂胞。

織入(Weaving):將增強(qiáng)處理增加到目標(biāo)對象中,并創(chuàng)建一個(gè)被增強(qiáng)的對象(AOP代理)的過程就是織入条篷∑妫織入有兩種實(shí)現(xiàn)方式:編譯時(shí)增強(qiáng)(例如AspectJ)和運(yùn)行時(shí)增強(qiáng)(例如CGLIB)

目前Spring只支持將方法調(diào)用作為連接點(diǎn),如果需要把Field的訪問和更新也作為增強(qiáng)處理的連接點(diǎn)赴叹,可以使用AspectJ鸿染。
一旦我們掌握了上面的AOP的相關(guān)概念,不難發(fā)現(xiàn)進(jìn)行AOP的編程其實(shí)是一件很簡單的事情乞巧,縱觀AOP編程需要程序員參與的只有3個(gè)部分

1.定義普通業(yè)務(wù)組件涨椒;
2.定義切入點(diǎn),一個(gè)切入點(diǎn)橫切多個(gè)業(yè)務(wù)組件绽媒;
3.定義增強(qiáng)處理蚕冬,增強(qiáng)處理就是現(xiàn)在AOP框架為普通業(yè)務(wù)組件織入的處理動作。

AOP是辕,基于Annotation的零配置方式

定義Before增強(qiáng)處理

當(dāng)我們在一個(gè)切面類里使用@Before來標(biāo)注一個(gè)方法時(shí)囤热,該方法將作為Before增強(qiáng)處理,使用@Before標(biāo)注時(shí)通常要指定一個(gè)value屬性值免糕,用來指定一個(gè)切入點(diǎn)表達(dá)式(既可以是一個(gè)已有的切入點(diǎn)赢乓,也可以直接定義切入點(diǎn)表達(dá)式)忧侧,用于指定該增強(qiáng)處理將被織入那些切入點(diǎn)。

注意:("execution( * cn.huaxia.spring.*.*(..))")第一個(gè)星號后面一定要有一個(gè)空格牌芋。

//定義一個(gè)切面
@Aspect
public class BeforeAdviceTest {
// 執(zhí)行cn.huaxia.spring包下的所有方法都做為切入點(diǎn)
@Before("execution(* cn.hb.spring..(..))")
public void authority() {
System.out.println("模擬執(zhí)行權(quán)限檢查...");
}
}

>上面**@Aspect**標(biāo)注BeforeAdviceTest 表明該類是一個(gè)切面類蚓炬,在該切面里定義了一個(gè)authority()方法,這個(gè)方法本來沒有什么特別之處躺屁,但是因?yàn)槭褂?*@Before**來標(biāo)注該方法肯夏,這就將該方法轉(zhuǎn)換成一個(gè)增強(qiáng)處理。上面程序中使用**@Before Annotation**標(biāo)注時(shí)犀暑,直接指定切入點(diǎn)表達(dá)式驯击,指定cn.hb.spring下的所有方法都作為切入點(diǎn)。

>```
@Component
public class Chinese implements Person {
    @Override
    public String sayHello(String word) {
        return word;
    }
    public void eat(String food) {
        System.out.println("我正在吃" + food);
    }
}

從上面Chinese類的代碼來看耐亏,他是一個(gè)如此純凈的Java類徊都,他絲毫不知將被誰來進(jìn)行增強(qiáng)處理,也不知道將被怎樣增強(qiáng)處理---正式這種無知才是"AOP"最大的魅力:目標(biāo)類可以被無限增強(qiáng)广辰。

在Spring配置文件中配置自動搜索Bean組件暇矫,配置自動搜索切面類,Spring AOP自動對Bean組件進(jìn)行增強(qiáng)择吊。配置文件如下:

<context:component-scanbase-package="cn.hb.spring">
<context:include-filtertype="annotation"
expression="org.aspectj.lang.annotation.Aspect"/>
</context:component-scan>
<!-- 啟動AspectJ支持-->
<aop:aspectj-autoproxy/>

編寫Junit類:

public class TestBefore {
    static ApplicationContext ac =null;
    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        ac =new ClassPathXmlApplicationContext("beans.xml");
    }
    @Test
    public void testBefore() {
    //Chinese c = (Chinese)ac.getBean("chinese");//會出錯(cuò)李根,不能轉(zhuǎn)換為Chinese
        Person c = (Person)ac.getBean("chinese");
        c.eat("西瓜");
        System.out.println(c.sayHello("你好--Before"));
    }
}

注意:Chinese c = (Chinese)ac.getBean("chinese");//會出錯(cuò),不能轉(zhuǎn)換為Chinese這里出錯(cuò)的原因是:
在默認(rèn)情況下几睛,如果一個(gè)目標(biāo)對象如果實(shí)現(xiàn)了接口Spring則會選擇JDK動態(tài)代理策略動態(tài)的創(chuàng)建一個(gè)接口實(shí)現(xiàn)類(動態(tài)代理類)來代理目標(biāo)對象房轿,可以通俗的理解這個(gè)動態(tài)代理類是目標(biāo)對象的另外一個(gè)版本,所以這兩者之間在強(qiáng)制轉(zhuǎn)換的時(shí)候會拋出java.lang.ClassCastException所森。而所以在默認(rèn)情況下囱持,如果目標(biāo)對象沒有實(shí)現(xiàn)任何接口,Spring會選擇CGLIB代理必峰, 其生成的動態(tài)代理對象是目標(biāo)類的子類洪唐。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末钻蹬,一起剝皮案震驚了整個(gè)濱河市吼蚁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌问欠,老刑警劉巖肝匆,帶你破解...
    沈念sama閱讀 221,888評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異顺献,居然都是意外死亡旗国,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評論 3 399
  • 文/潘曉璐 我一進(jìn)店門注整,熙熙樓的掌柜王于貴愁眉苦臉地迎上來能曾,“玉大人度硝,你說我怎么就攤上這事∈倜幔” “怎么了蕊程?”我有些...
    開封第一講書人閱讀 168,386評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長驼唱。 經(jīng)常有香客問我藻茂,道長,這世上最難降的妖魔是什么玫恳? 我笑而不...
    開封第一講書人閱讀 59,726評論 1 297
  • 正文 為了忘掉前任辨赐,我火速辦了婚禮,結(jié)果婚禮上京办,老公的妹妹穿的比我還像新娘掀序。我一直安慰自己,他們只是感情好惭婿,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,729評論 6 397
  • 文/花漫 我一把揭開白布森枪。 她就那樣靜靜地躺著,像睡著了一般审孽。 火紅的嫁衣襯著肌膚如雪县袱。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,337評論 1 310
  • 那天佑力,我揣著相機(jī)與錄音式散,去河邊找鬼。 笑死打颤,一個(gè)胖子當(dāng)著我的面吹牛暴拄,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播编饺,決...
    沈念sama閱讀 40,902評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼乖篷,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了透且?” 一聲冷哼從身側(cè)響起撕蔼,我...
    開封第一講書人閱讀 39,807評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎秽誊,沒想到半個(gè)月后鲸沮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,349評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡锅论,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,439評論 3 340
  • 正文 我和宋清朗相戀三年讼溺,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片最易。...
    茶點(diǎn)故事閱讀 40,567評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡怒坯,死狀恐怖炫狱,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情剔猿,我是刑警寧澤毕荐,帶...
    沈念sama閱讀 36,242評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站艳馒,受9級特大地震影響憎亚,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜弄慰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,933評論 3 334
  • 文/蒙蒙 一第美、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧陆爽,春花似錦什往、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至驴剔,卻和暖如春省古,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背丧失。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評論 1 272
  • 我被黑心中介騙來泰國打工豺妓, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人布讹。 一個(gè)月前我還...
    沈念sama閱讀 48,995評論 3 377
  • 正文 我出身青樓琳拭,卻偏偏與公主長得像,于是被迫代替她去往敵國和親描验。 傳聞我的和親對象是個(gè)殘疾皇子白嘁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,585評論 2 359

推薦閱讀更多精彩內(nèi)容

  • AOP實(shí)現(xiàn)可分為兩類(按AOP框架修改源代碼的時(shí)機(jī)): 靜態(tài)AOP實(shí)現(xiàn):AOP框架在編譯階段對程序進(jìn)行修改絮缅,即實(shí)現(xiàn)...
    數(shù)獨(dú)題閱讀 2,324評論 0 22
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)睡扬,斷路器盟蚣,智...
    卡卡羅2017閱讀 134,702評論 18 139
  • 當(dāng)相同的切面里的兩個(gè)增強(qiáng)處理需要在相同的連接點(diǎn)被織入時(shí)黍析,Spring AOP將以隨機(jī)的方式來織入這兩個(gè)增強(qiáng)處理卖怜,沒...
    FTOLsXD閱讀 1,263評論 0 1
  • **** AOP 面向切面編程 底層原理 代理!2妗马靠! 今天AOP課程1奄抽、 Spring 傳統(tǒng) AOP2、 Spri...
    luweicheng24閱讀 1,371評論 0 1
  • 本章內(nèi)容: 面向切面編程的基本原理 通過POJO創(chuàng)建切面 使用@AspectJ注解 為AspectJ切面注入依賴 ...
    謝隨安閱讀 3,157評論 0 9