Spring特性IOC-AOP筆記

Spring擁有兩大特性:IoC和AOP。IoC,英文全稱Inversion of Control,意為控制反轉(zhuǎn)。AOP,英文全稱Aspect-Oriented Programming,意為面向切面編程。
Spring核心容器的主要組件是Bean工廠(BeanFactory),Bean工廠使用控制反轉(zhuǎn)(IoC)模式來降低程序代碼之間的耦合度,并提供了面向切面編程(AOP)的實(shí)現(xiàn)。
簡(jiǎn)單來說,Spring是一個(gè)輕量級(jí)的控制反轉(zhuǎn)(IoC)和面向切面編程(AOP)的容器框架。
?控制反轉(zhuǎn)(IoC)
控制反轉(zhuǎn),簡(jiǎn)單點(diǎn)說,就是創(chuàng)建對(duì)象的控制權(quán),被反轉(zhuǎn)到了Spring框架上。
通常,我們實(shí)例化一個(gè)對(duì)象時(shí),都是使用類的構(gòu)造方法來new一個(gè)對(duì)象,這個(gè)過程是由我們自己來控制的,而控制反轉(zhuǎn)就把new對(duì)象的工交給了Spring容器。
先來說說傳統(tǒng)使用java實(shí)例的不足,一般有兩種方式:
通過new關(guān)鍵字實(shí)例化一個(gè)對(duì)象;
通過工廠模式生產(chǎn)一個(gè)實(shí)例對(duì)象;
第一種方式必然導(dǎo)致調(diào)用者和被依賴對(duì)象存在硬編碼耦合,非常不利于項(xiàng)目升級(jí)的維護(hù);第二種比第一種好很多,但是調(diào)用組件需要主動(dòng)通過工廠去獲取被依賴的對(duì)象,這就會(huì)帶來調(diào)用組件與被依賴工廠的耦合。
那么IOC有什么好處呢?
調(diào)用者無需主動(dòng)獲取被依賴的對(duì)象,只要被動(dòng)接受Spring容器為調(diào)用者的成員變量即可。總體來說就是主動(dòng)變?yōu)楸粍?dòng),所以被稱為控制反轉(zhuǎn)。
場(chǎng)景
依賴注入一般有以下兩種:
設(shè)值注入:IoC容器使用成員變量的setter方法來注入被依賴對(duì)象;
構(gòu)造注入:IoC容器通過構(gòu)造器來注入被依賴對(duì)象;
建議采用設(shè)值注入為主,構(gòu)造注入為輔的注入策略。對(duì)于依賴關(guān)系無需變化的注入,盡量采用構(gòu)造注入;而其他依賴關(guān)系的注入,則考慮采用設(shè)值注入。
使用IoC容器的三個(gè)基本要點(diǎn):
應(yīng)用程序的各組件面向接口編程,這樣就可以將組件之間的耦合關(guān)系提升到接口層次,從而有有利于項(xiàng)目后期的發(fā)展;
應(yīng)用程序的各組件不再由程序主動(dòng)創(chuàng)建,而是由Spring容器來負(fù)責(zé)產(chǎn)生并初始化;
Spring采用配置文件或注解來管理Bean的實(shí)現(xiàn)類、依賴關(guān)系,Spring容器則根據(jù)配置文件或注解,利用反射來創(chuàng)建實(shí)例,并為之注入依賴關(guān)系。
?面向切面編程(AOP)
面向切面編程(AOP)就是縱向的編程。比如業(yè)務(wù)A和業(yè)務(wù)B現(xiàn)在需要一個(gè)相同的操作,傳統(tǒng)方法我們可能需要在A、B中都加入相關(guān)操作代碼,而應(yīng)用AOP就可以只寫一遍代碼,A、B共用這段代碼。并且,當(dāng)A、B需要增加新的操作時(shí),可以在不改動(dòng)原代碼的情況下,靈活添加新的業(yè)務(wù)邏輯實(shí)現(xiàn)。
在實(shí)際開發(fā)中,比如商品查詢、促銷查詢等業(yè)務(wù),都需要記錄日志、異常處理等操作,AOP把所有共用代碼都剝離出來,單獨(dú)放置到某個(gè)類中進(jìn)行集中管理,在具體運(yùn)行時(shí),由容器進(jìn)行動(dòng)態(tài)織入這些公共代碼。
AOP主要一般應(yīng)用于簽名驗(yàn)簽、參數(shù)校驗(yàn)、日志記錄、事務(wù)控制、權(quán)限控制、性能統(tǒng)計(jì)、異常處理等。
AOP涉及名詞
切面(Aspect):共有功能的實(shí)現(xiàn)。如日志切面、權(quán)限切面、驗(yàn)簽切面等。在實(shí)際開發(fā)中通常是一個(gè)存放共有功能實(shí)現(xiàn)的標(biāo)準(zhǔn)Java類。當(dāng)Java類使用了@Aspect注解修飾時(shí),就能被AOP容器識(shí)別為切面。
通知(Advice):切面的具體實(shí)現(xiàn)。就是要給目標(biāo)對(duì)象織入的事情。以目標(biāo)方法為參照點(diǎn),根據(jù)放置的地方不同,可分為前置通知(Before)、后置通知(AfterReturning)、異常通知(AfterThrowing)、最終通知(After)與環(huán)繞通知(Around)5種。在實(shí)際開發(fā)中通常是切面類中的一個(gè)方法,具體屬于哪類通知,通過方法上的注解區(qū)分。
連接點(diǎn)(JoinPoint):程序在運(yùn)行過程中能夠插入切面的地點(diǎn)。例如,方法調(diào)用、異常拋出等。Spring只支持方法級(jí)的連接點(diǎn)。一個(gè)類的所有方法前、后、拋出異常時(shí)等都是連接點(diǎn)。
切入點(diǎn)(Pointcut):用于定義通知應(yīng)該切入到哪些連接點(diǎn)上。不同的通知通常需要切入到不同的連接點(diǎn)上,這種精準(zhǔn)的匹配是由切入點(diǎn)的正則表達(dá)式來定義的。
比如,在上面所說的連接點(diǎn)的基礎(chǔ)上,來定義切入點(diǎn)。我們有一個(gè)類,類里有10個(gè)方法,那就產(chǎn)生了幾十個(gè)連接點(diǎn)。但是我們并不想在所有方法上都織入通知,我們只想讓其中的幾個(gè)方法,在調(diào)用之前檢驗(yàn)下入?yún)⑹欠窈戏ǎ敲淳陀们悬c(diǎn)來定義這幾個(gè)方法,讓切點(diǎn)來篩選連接點(diǎn),選中我們想要的方法。切入點(diǎn)就是來定義哪些類里面的哪些方法會(huì)得到通知。
目標(biāo)對(duì)象(Target):那些即將切入切面的對(duì)象,也就是那些被通知的對(duì)象。這些對(duì)象專注業(yè)務(wù)本身的邏輯,所有的共有功能等待AOP容器的切入。
代理對(duì)象(Proxy):將通知應(yīng)用到目標(biāo)對(duì)象之后被動(dòng)態(tài)創(chuàng)建的對(duì)象??梢院?jiǎn)單地理解為,代理對(duì)象的功能等于目標(biāo)對(duì)象本身業(yè)務(wù)邏輯加上共有功能。代理對(duì)象對(duì)于使用者而言是透明的,是程序運(yùn)行過程中的產(chǎn)物。目標(biāo)對(duì)象被織入共有功能后產(chǎn)生的對(duì)象。
織入(Weaving):將切面應(yīng)用到目標(biāo)對(duì)象從而創(chuàng)建一個(gè)新的代理對(duì)象的過程。這個(gè)過程可以發(fā)生在編譯時(shí)、類加載時(shí)、運(yùn)行時(shí)。Spring是在運(yùn)行時(shí)完成織入,運(yùn)行時(shí)織入通過Java語(yǔ)言的反射機(jī)制與動(dòng)態(tài)代理機(jī)制來動(dòng)態(tài)實(shí)現(xiàn)。
Aspect Oriented Programming,面向切面編程,用于在模塊化方面的橫切關(guān)注點(diǎn)。AOP和OOP(Object Oriented Programming)互為補(bǔ)充,可以這么理解:面向?qū)ο缶幊淌菑撵o態(tài)角度縱向考慮程序結(jié)構(gòu),面向切面編程則是從動(dòng)態(tài)角度橫向考慮運(yùn)行過程。比如一個(gè)日記記錄的功能,代碼往往水平的散落在所有對(duì)象中,與被散布的對(duì)象的核心功能沒什么關(guān)系,這種散布在各個(gè)對(duì)象中的無關(guān)代碼被稱為“橫切代碼”,在OOP的設(shè)計(jì)中,它導(dǎo)致了大量代碼的重復(fù),從而不利于各個(gè)模塊的復(fù)用。
簡(jiǎn)單的說,它是一個(gè)攔截器可以攔截一些過程,當(dāng)一個(gè)方法執(zhí)行,Spring AOP可以攔截一個(gè)方法的執(zhí)行,在這個(gè)方法執(zhí)行的前后添加一些功能。是一個(gè)典型代理模式的應(yīng)用。
使用場(chǎng)景
日志記錄、審計(jì)、聲明式事務(wù)、安全性和緩存等。
總結(jié)
IoC,(Inverse of Control)控制反轉(zhuǎn),其包含兩個(gè)內(nèi)容:其一是控制,其二是反轉(zhuǎn)。在程序中,被調(diào)用類的選擇控制權(quán)從調(diào)用它的類中移除,轉(zhuǎn)交給第三方裁決。這個(gè)第三方指的就是Spring的容器。IoC另解,依賴注入(Dependency Injection),調(diào)用類對(duì)被調(diào)用類的依賴關(guān)系由第三方注入,以移除調(diào)用類對(duì)被調(diào)用類的引用。
aop,面向切面編程(也叫面向方面):Aspect Oriented Programming(AOP),是目前軟件開發(fā)中的一個(gè)熱點(diǎn),也是Spring框架中的一個(gè)重要內(nèi)容。利用AOP可以對(duì)業(yè)務(wù)邏輯的各個(gè)部分進(jìn)行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可重用性,同時(shí)提高了開發(fā)的效率。 AOP是OOP的延續(xù),是(Aspect Oriented Programming)的縮寫,意思是面向切面(方面)編程。主要的功能是:日志記錄,性能統(tǒng)計(jì),安全控制,事務(wù)處理,異常處理等等。 主要的意圖是:將日志記錄,性能統(tǒng)計(jì),安全控制,事務(wù)處理,異常處理等代碼從業(yè)務(wù)邏輯代碼中劃分出來,通過對(duì)這些行為的分離,我們希望可以將它們獨(dú)立到非指導(dǎo)業(yè)務(wù)邏輯的方法中,進(jìn)而改 變這些行為的時(shí)候不影響業(yè)務(wù)邏輯的代碼。