Spring AOP 筆記三(引入Introductions)

此文是Sping in Action 第4版 英文原版切面部分的讀書(shū)筆記微驶,僅限交流使用银舱,有不足之處屑咳,一定聽(tīng)取修改。

系列目錄:
Spring AOP 筆記一(基礎(chǔ)概念柑蛇,一個(gè)簡(jiǎn)單切面)
Spring AOP 筆記二(環(huán)繞通知芥挣,切面中獲取參數(shù))
Spring AOP 筆記三(切面注解引入新的方法)

1. 注解引入(Annotating introductions)

在一些高級(jí)語(yǔ)言中,比如Rudy與Groovy耻台,都有開(kāi)放類(lèi)的概念空免,能夠在不改變對(duì)象和類(lèi)的代碼的前提下,為對(duì)象和類(lèi)添加新的方法盆耽。然而對(duì)于Java蹋砚,很不幸,他不是動(dòng)態(tài)的征字,類(lèi)一旦編譯完成都弹,就很難再為他添加新的功能娇豫。
但是你可以稍微想一想我們?cè)俅沃皩?xiě)的切面匙姜。雖然沒(méi)有為向?qū)ο笾刑砑有碌姆椒ǎ且呀?jīng)向其中添加了新的功能冯痢。既然我們能夠向現(xiàn)有的方法添加新的功能氮昧,為什么不能為一個(gè)對(duì)象添加新的方法那框杜?實(shí)際上,使用名為 引入(introduction) 的AOP概念袖肥,就能夠?qū)崿F(xiàn)咪辱。

之前好像沒(méi)有提到切面實(shí)現(xiàn)的原理。切面是用到了叫做 代理 的設(shè)計(jì)模式椎组。這里簡(jiǎn)單比喻一下油狂,代理就好像是藝人(被切入的bean的方法)盡心盡責(zé)的經(jīng)紀(jì)人[笑臉],在日常工作中寸癌,外部的通告或者節(jié)目邀請(qǐng)都會(huì)先送到經(jīng)紀(jì)人的手里专筷,經(jīng)紀(jì)人會(huì)自己幫助藝人處理完一些必須事務(wù)(@before),,不需要藝人關(guān)系或者插手蒸苇,然后經(jīng)紀(jì)人處理完后磷蛹,再告知(調(diào)用)藝人,去演戲或者參加節(jié)目溪烤,例如下圖:

基本的代理

感興趣的同學(xué)可以深入學(xué)習(xí)一下味咳。

于是乎當(dāng)我們想在對(duì)象中加入新的方法時(shí),比如當(dāng)前的藝人擅長(zhǎng)表演檬嘀,而有些節(jié)目想讓他獻(xiàn)聲槽驶,此時(shí)經(jīng)紀(jì)人就可以找個(gè)會(huì)唱歌的藝人(一個(gè)新的接口,里面有我們想要新增得唱歌方法)鸳兽,當(dāng)欄目索要(調(diào)用)歌曲時(shí)捺檬,此時(shí)經(jīng)紀(jì)人就可以直接讓唱歌的藝人唱一首歌送個(gè)欄目,在欄目(調(diào)用者)那里贸铜,并不會(huì)知道是誰(shuí)完成可唱歌這個(gè)任務(wù)堡纬,如下圖:

添加新的方法

這樣說(shuō)應(yīng)該差不多能理解。

然后看一個(gè)小栗子:

我們先定義一個(gè)Singer接口蒿秦,代表會(huì)唱歌的藝人烤镐。
/* 
* 一個(gè)歌者 
* Created by Henvealf on 2016/9/3. 
*/
public interface Singer { 
        void sing();
}
然后新定義一個(gè)切面,類(lèi)名為SingerIntroducer棍鳖,歌手引入者炮叶,也就是經(jīng)紀(jì)人。
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.DeclareParents;
/** 
* 歌手引入者 
* Created by Henvealf on 2016/9/3. 
*/
@Aspectpublic 
class SingerIntroducer {           
     @DeclareParents(value="com.mengxiang.concert.Performance+", 
                defaultImpl = BackSinger.class)
     public static Singer singer;
}

可以發(fā)現(xiàn)他沒(méi)有前置before渡处,后置after或環(huán)繞round通知镜悉,只有一個(gè) @DeclareParents ,通過(guò)她,就能將 Singer 接口的實(shí)現(xiàn)引入到 Performance 的實(shí)現(xiàn)類(lèi)中医瘫,即相當(dāng)于Performance 得到了新的方法侣肄。

詳細(xì)解釋一下:

  • value 指定了哪個(gè)類(lèi)的bean將會(huì)被引入@DeclareParents 注解的接口。在上面的例子中醇份,Performance 后面的加號(hào)表示的是所有 Performance的子類(lèi)型稼锅,而不是 Performance 本身吼具。

  • defaultImpl 屬性就指定了一個(gè)明確的 Singer 接口的實(shí)現(xiàn)類(lèi),只有接口是沒(méi)用的矩距,所以就需要用他來(lái)提供引入一個(gè)接口的具體實(shí)現(xiàn)拗盒。

  • 那最后 @DeclareParents 注解的 Singer 就是要被引入的接口(Singer)了。注意這里是靜態(tài)的锥债。

所以很明顯陡蝇,我們需要寫(xiě)一個(gè)名為 BackSingerSinger的實(shí)現(xiàn)類(lèi),幕后歌者:
/** 
* 幕后歌者 
* Created by Henvealf on 2016/9/3. 
*/
public class BackSinger implements Singer{ 
      public void sing() { 
              System.out.println("嘿嘿嘿~~~哈哈哈~~~你們?nèi)ツ睦锇哮肚。毅整。。?); 
      }
}
最后將 Performance 的實(shí)現(xiàn)dancer 與切面 SingerIntroducer 注入到容器中绽左。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import javax.sound.midi.Track;
/** 
* 
* Created by Henvealf on 2016/8/26. 
*/
@Configuration
@EnableAspectJAutoProxy
@ComponentScan("com.henvealf.learn.spring.concert")
public class ConcertConfig { 
        @Bean(name = "dancer") 
        public Performance dancer(){ 
                return new Dancer(); 
        } 
        @Bean 
        SingerIntroducer singerIntroducer(){ 
                return new SingerIntroducer(); 
        }
}

關(guān)于 dance 可以查看 Spring AOP 筆記一(基礎(chǔ)概念悼嫉,一個(gè)簡(jiǎn)單切面)

最后就是運(yùn)行看看效果了。

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/** 
* 
* 
Created by Henvealf on 2016/8/27.
 */
public class Main { 
    public static void main(String[] args) {
        ApplicationContext context =
                 new AnnotationConfigApplicationContext("com.mengxiang.concert"); 
        Performance per = (Performance) context.getBean("dancer"); 
        Singer singer = (Singer)per; singer.sing(); 
        //或者這樣: 
        //((Singer)per).sing(); 
    }
}

執(zhí)行結(jié)果:

嘿嘿嘿~~~哈哈哈~~~你們?nèi)ツ睦锇拼窥。戏蔑。。?/p>

我們可以發(fā)現(xiàn)鲁纠,為了執(zhí)行在Performance中引入的sing()方法总棵,需要先將其bean轉(zhuǎn)型為Singer類(lèi)型才能執(zhí)行sing()方法,偽裝一下改含,不然被人發(fā)現(xiàn)可就鬧大發(fā)了情龄,編譯器自己就不愿意。

本篇就結(jié)束嘍捍壤! 謝謝大家的支持骤视!或許還有下一篇 !

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市鹃觉,隨后出現(xiàn)的幾起案子专酗,更是在濱河造成了極大的恐慌,老刑警劉巖盗扇,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件祷肯,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡疗隶,警方通過(guò)查閱死者的電腦和手機(jī)佑笋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)斑鼻,“玉大人蒋纬,你說(shuō)我怎么就攤上這事。” “怎么了颠锉?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵法牲,是天一觀的道長(zhǎng)史汗。 經(jīng)常有香客問(wèn)我琼掠,道長(zhǎng),這世上最難降的妖魔是什么停撞? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任瓷蛙,我火速辦了婚禮,結(jié)果婚禮上戈毒,老公的妹妹穿的比我還像新娘艰猬。我一直安慰自己,他們只是感情好埋市,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布冠桃。 她就那樣靜靜地躺著,像睡著了一般道宅。 火紅的嫁衣襯著肌膚如雪食听。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,708評(píng)論 1 305
  • 那天污茵,我揣著相機(jī)與錄音樱报,去河邊找鬼。 笑死泞当,一個(gè)胖子當(dāng)著我的面吹牛迹蛤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播襟士,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼盗飒,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了陋桂?” 一聲冷哼從身側(cè)響起箩兽,我...
    開(kāi)封第一講書(shū)人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎章喉,沒(méi)想到半個(gè)月后汗贫,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡秸脱,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年落包,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片摊唇。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡咐蝇,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出巷查,到底是詐尸還是另有隱情有序,我是刑警寧澤抹腿,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站旭寿,受9級(jí)特大地震影響警绩,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜盅称,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一肩祥、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧缩膝,春花似錦混狠、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至痛黎,卻和暖如春予弧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背舅逸。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工桌肴, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人琉历。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓坠七,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親旗笔。 傳聞我的和親對(duì)象是個(gè)殘疾皇子彪置,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

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