AOP簡(jiǎn)介
在這里向說一件之前生活中比較常見的事情就是抄電表,電表在我們?nèi)粘5纳钪泻艹R姼哿睿挥形覀冇秒娝驮谟涗浳覀冇玫碾娏浚欢螘r(shí)間后就會(huì)有人來抄電表锈颗。在這個(gè)中電表只記錄我們的用電量顷霹,而不用管電量的統(tǒng)計(jì)等。而軟件系統(tǒng)中的一些功能就像電表一樣击吱,這些功能需要用到應(yīng)用程序的多個(gè)地方淋淀,但是我們又不希望在每個(gè)點(diǎn)都明確的調(diào)用她們。比如我們常用的日志覆醇、安全和事務(wù)管理朵纷。如果我們讓應(yīng)用對(duì)象關(guān)注自己的業(yè)務(wù)邏輯,其他方面的都交給其他的對(duì)象來處理永脓,這些會(huì)顯得代碼更加的精簡(jiǎn)袍辞、清晰。
在軟件中這些散布于應(yīng)用中多處的功能被稱為橫切關(guān)注點(diǎn)(日志憨奸、安全等)(cross-cutting concern)革屠。通常來說,這些橫切的關(guān)注點(diǎn)是和應(yīng)用的業(yè)務(wù)邏輯分離的(當(dāng)時(shí)在很多地方是嵌入在應(yīng)用的業(yè)務(wù)邏輯中排宰,而AOP做的就是把這些關(guān)注點(diǎn)和業(yè)務(wù)邏輯分開,那么AOP到底是什么那婉?
AOP是Aspect Oriented Programing的簡(jiǎn)稱板甘,被譯為“面向切面的編程”。按照應(yīng)用程序重構(gòu)的思想详炬,如果多個(gè)類中出現(xiàn)了相同的代碼盐类,那么就應(yīng)該考慮將這些相同的代碼抽象出來定義成一個(gè)父類或者使用委托,但是如果在整個(gè)的應(yīng)用程序中都是用相同的一個(gè)或者幾個(gè)基類呛谜,往往會(huì)導(dǎo)致應(yīng)用程序變得更加復(fù)雜在跳。而面向切面可以替代繼承和委托,而且在很多的場(chǎng)合下可以使程序變得更加的簡(jiǎn)潔隐岛。
AOP中的一些術(shù)語
和大多數(shù)的技術(shù)一樣猫妙,AOP也有自己的一些術(shù)語。這些術(shù)語用于描述一個(gè)切面聚凹。
- 連接點(diǎn)(Joinpoint)
連接點(diǎn)是程序執(zhí)行的某個(gè)特定的位置割坠,如類的初始化前齐帚、類的初始化后、類的某個(gè)方法調(diào)用前彼哼,每個(gè)方法調(diào)用后对妄、方法拋出以上后。一個(gè)類或者一段程序代碼擁有一些具有邊界性質(zhì)的特殊點(diǎn)敢朱。
- 切點(diǎn)(Pointcut)
每個(gè)程序都擁有多個(gè)連接點(diǎn)剪菱,如一個(gè)擁有兩個(gè)方法的類,這兩個(gè)方法都是連接點(diǎn)拴签,即連接點(diǎn)是程序類中客觀存在的事物孝常。簡(jiǎn)單的來說也就是連接點(diǎn)都是可以切入的點(diǎn),每一次我們可以選擇一些特點(diǎn)的連接點(diǎn)切入篓吁,而我們所選的這些連接點(diǎn)就是切點(diǎn)茫因。可以通過數(shù)據(jù)庫的查詢來理解切點(diǎn)和連接點(diǎn)之間的關(guān)系:連接點(diǎn)相當(dāng)于數(shù)據(jù)庫中的記錄(也就是所有能夠連接的點(diǎn))杖剪,而切點(diǎn)相當(dāng)與查詢條件冻押。切點(diǎn)和連接點(diǎn)不是一一對(duì)應(yīng)的關(guān)系,一個(gè)切點(diǎn)可以匹配多個(gè)連接點(diǎn)盛嘿。
- 增強(qiáng)(Advice)
增強(qiáng)是織入連接點(diǎn)上的一段程序洛巢。向記錄日志等,我們可以在應(yīng)用程序邏輯方法完成后次兆,去增強(qiáng)這個(gè)方法稿茉,也就是選擇這個(gè)類的這個(gè)方法作為切點(diǎn),去織入一段程序記錄日志芥炭。相當(dāng)于動(dòng)態(tài)的封裝這個(gè)方法漓库。
- 目標(biāo)對(duì)象
增強(qiáng)邏輯的織入目標(biāo)類。如果沒有AOP园蝠,那么目標(biāo)業(yè)務(wù)類需要自己實(shí)現(xiàn)所有的邏輯渺蒿。
- 引介(Introduction)
引介是一種特殊的增強(qiáng),她為類添加一些屬性方法彪薛。這樣茂装,及時(shí)一個(gè)業(yè)務(wù)類原本沒有實(shí)現(xiàn)某個(gè)接口,通過AOP的引介功能善延,也可以動(dòng)態(tài)地為該業(yè)務(wù)類添加接口實(shí)現(xiàn)邏輯少态。
- 織入(Weaving)
織入是將增強(qiáng)添加到目標(biāo)類的具體連接點(diǎn)上的過程。從名字上也可以看出易遣,AOP就像織布機(jī)一樣彼妻,將目標(biāo)類,增強(qiáng)編制在一起训挡。根據(jù)不同的實(shí)現(xiàn)技術(shù)澳骤,AOP有三種織入方式歧强。
(1)編譯期織入:切面在目標(biāo)類編譯時(shí)被織入,這要求需用使用特殊的Java編譯器为肮。
(2)類裝載期被織入:切面在目標(biāo)類加載到JVM時(shí)被織入摊册,這種方式需要特殊的類加載器(ClassLoader),它可以在目標(biāo)類引入應(yīng)用之前增強(qiáng)該目標(biāo)類的字節(jié)碼颊艳。
(3)動(dòng)態(tài)代理織入茅特,在運(yùn)行期為目標(biāo)類添加增強(qiáng)生成子類的方式。
Spring采用動(dòng)態(tài)代理織入棋枕,AspectJ采用編譯器織入和類裝載期織入白修。
- 代理(Proxy)
一個(gè)類別AOP增強(qiáng)之后,就會(huì)產(chǎn)生一個(gè)新的類重斑,他是如何了袁磊和增強(qiáng)邏輯的代理類兵睛。根據(jù)不同的代理方式,代理類既可以和原類具有相同接口的類窥浪,也可能就是原來的類祖很,所以可以采用和調(diào)用原類相同的方式調(diào)用代理類。
- 切面(Aspect)
切面有切點(diǎn)和增強(qiáng)(引介)組成漾脂,它既包括了橫切邏輯的定義假颇,也包括連接點(diǎn)的定義。
AOP的實(shí)現(xiàn)者
- AspectJ
AspectJ是一個(gè)面向切面的框架骨稿,2001年有Xerox PARC的AOP小組發(fā)布笨鸡,它擴(kuò)展了Java語言。AspectJ定義了AOP語法坦冠,所以它有一個(gè)專門的編譯器用來生成遵守Java字節(jié)編碼規(guī)范的Class文件形耗。
- AspectWerkz
AspectWerkz是基于Java的簡(jiǎn)單、動(dòng)態(tài)辙浑、輕量級(jí)的AOP框架趟脂,該框架發(fā)布于2002年,有BEA Systems提供支持例衍。它支持運(yùn)行期或類裝載期織入橫切代碼,它也有一個(gè)特殊的類裝載器∫研叮現(xiàn)在AspectJ和AspectWerkz項(xiàng)目已經(jīng)合并佛玄,它們合作的第一個(gè)發(fā)布版是AspectJ 5:擴(kuò)展AspectJ語言,以注解的方式支持類似AspectJ的代碼風(fēng)格累澡。
- Jboss AOP
JBoss AOP于2004年作為JBoss應(yīng)用服務(wù)器框架的擴(kuò)展功能發(fā)布梦抢。
- Spring AOP
Spring AOP使用純Java實(shí)現(xiàn),他不需要專門的編譯過程愧哟,也不需要特殊的類裝載器奥吩,他在運(yùn)行期通過代理方式向目標(biāo)類中織入增強(qiáng)代碼哼蛆。