面向切面編程_第1頁(yè)
面向切面編程_第2頁(yè)
面向切面編程_第3頁(yè)
面向切面編程_第4頁(yè)
面向切面編程_第5頁(yè)
已閱讀5頁(yè),還剩39頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第14章

面向切面編程SpringAOP簡(jiǎn)介

面向切面編程(AOP)提供另外一種角度來思考程序結(jié)構(gòu),通過這種方式彌補(bǔ)了面向?qū)ο缶幊蹋∣OP)的不足。除了類(classes)以外,AOP提供了切面。切面對(duì)關(guān)注點(diǎn)進(jìn)行模塊化,例如橫切多個(gè)類型和對(duì)象的事務(wù)管理。在AOP中,把分散程序各個(gè)部分,解決同樣問題的代碼片段,稱為問題的切面(或方面)。一個(gè)切面可以簡(jiǎn)單的理解為解決跨越多個(gè)模塊的交叉關(guān)注點(diǎn)問題的模塊。通過AOP可以使用一種非常簡(jiǎn)單、靈活的方式,在切面中實(shí)現(xiàn)了以前需要在各個(gè)核心關(guān)注點(diǎn)中穿插的交叉關(guān)注的功能,從而使得解決系統(tǒng)中交叉關(guān)注點(diǎn)問題的模塊更加容易設(shè)計(jì)、實(shí)現(xiàn)及維護(hù)。AOP相關(guān)框架及工具AspectJ:對(duì)java進(jìn)行了擴(kuò)展,形成一個(gè)功能強(qiáng)大、靈活、實(shí)用的AOP語(yǔ)言。AspectWerkz:一個(gè)動(dòng)態(tài)、輕量級(jí)、性能表現(xiàn)良好的AOP框架。JBoss-AOP:JBoss公司開發(fā)的基于方法攔截及源碼級(jí)數(shù)據(jù)的AOP實(shí)現(xiàn)框架。

Spring-AOP:使用基于代理及攔截器的機(jī)制,與SpringIOC容器融入一體的AOP框架。

AOP中的五種AdviceAOP中的相關(guān)術(shù)語(yǔ)

1)關(guān)注點(diǎn)(Concern)

關(guān)注點(diǎn)也就是我們要考察或解決的問題。把一個(gè)系統(tǒng)中的核心功能稱為核心關(guān)注點(diǎn)跨越多個(gè)模塊的關(guān)注點(diǎn)稱為橫切關(guān)注點(diǎn)或交叉關(guān)注點(diǎn)(CrosscuttingConcerns)。在AOP的編程方法中,主要在于對(duì)關(guān)注點(diǎn)的提起及抽象。2)切面(Aspect)

切面是一個(gè)抽象的概念,從軟件的角度來說是指在應(yīng)用程序不同模塊中的某一個(gè)領(lǐng)域或方面。

AOP中的切面(aspect)是實(shí)現(xiàn)世界領(lǐng)域問題的抽象,除了包括屬性、方法以外,同時(shí)切面中還包括切入點(diǎn)Pointcut、增強(qiáng)(advice)等。3)連接點(diǎn)(Joinpoint)

連接點(diǎn)也就是運(yùn)用程序執(zhí)行過程中需要插入切面模塊的某一點(diǎn)。這個(gè)點(diǎn)可以是一個(gè)方法、一個(gè)屬性、構(gòu)造函數(shù)、類靜態(tài)初始化塊,甚至一條語(yǔ)句。4)切入點(diǎn)(Pointcut)

切入點(diǎn)指一個(gè)或多個(gè)連接點(diǎn),可以理解成一個(gè)點(diǎn)的集合。切入點(diǎn)的描述比較具體,而且一般會(huì)跟連接點(diǎn)上下文環(huán)境結(jié)合。5)增強(qiáng)或通知(Advice)

增強(qiáng)(Advice)里面定義了切面中的實(shí)際邏輯(即實(shí)現(xiàn)),即法增強(qiáng)(Advice)是指在定義好的切入點(diǎn)處,所要執(zhí)行的程序代碼。Spring的AOP簡(jiǎn)介

AOP是Spring框架的重要組成部分。

SpringAOP使用純Java實(shí)現(xiàn),不需要專門的編譯過程。

Spring沒有像AspectJ那樣強(qiáng)大的功能,只支持與方法調(diào)用有關(guān)的連接點(diǎn)。

Spring中的AOP代理由Spring的Ioc容器負(fù)責(zé)生成、管理,其依賴關(guān)系也由Ioc容器負(fù)責(zé)管理。

AOP編程只需要程序員參加3個(gè)部分:定義普通業(yè)務(wù)組件定義切入點(diǎn)定義增強(qiáng)處理Spring有兩種方式定義切入點(diǎn)和增強(qiáng)處理:基于Annotation的方式:使用@Aspect、@PointCut等Annotation基于XML配置文件的管理方式:使用Spring的配置文件啟用@AspectJ支持為了在Spring配置中使用@AspectJaspects,必須首先啟用Spring對(duì)基于@AspectJaspects的配置支持,自動(dòng)代理(autoproxying)基于通知是否來自這些切面。自動(dòng)代理是指Spring會(huì)判斷一個(gè)bean是否使用了一個(gè)或多個(gè)切面通知,并據(jù)此自動(dòng)生成相應(yīng)的代理以攔截其方法調(diào)用,并且確認(rèn)通知是否如期進(jìn)行。

配置文件示例:

<?xmlversion="1.0"encoding="GBK"?><beansxmlns="http:///schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xmlns:context="http:///schema/context"xmlns:aop="http:///schema/aop"xsi:schemaLocation="http:///schema/beans/schema/beans/spring-beans-2.5.xsdhttp:///schema/context/schema/context/spring-context-2.5.xsdhttp:///schema/aop/schema/aop/spring-aop-2.5.xsd"><context:component-scanbase-package="lee"><context:include-filtertype="annotation"expression="org.aspectj.lang.annotation.Aspect"/></context:component-scan><aop:aspectj-autoproxy/></beans>Spring2支持的AspectJ標(biāo)簽@Aspect-標(biāo)識(shí)一個(gè)切面;@Pointcut-標(biāo)識(shí)一個(gè)切入點(diǎn);@Before-標(biāo)識(shí)一個(gè)前置增強(qiáng);@AfterReturning-標(biāo)識(shí)返回后增強(qiáng);@AfterThrowing-標(biāo)識(shí)異常拋出增強(qiáng);@After-標(biāo)識(shí)后增強(qiáng);@Around-標(biāo)識(shí)環(huán)繞增強(qiáng);1)定義切面Bean

當(dāng)啟動(dòng)了@AspectJ支持后,只要在Spring容器中配置一個(gè)@Aspect注釋的Bean,Spring將會(huì)自動(dòng)識(shí)別該Bean,并將該Bean作為切面處理。例如:@AspectpublicclassAspectTest{}

注意:當(dāng)使用@Aspect標(biāo)注一個(gè)Java類后,Spring將不會(huì)把該Bean當(dāng)成Bean組件處理。2)定義Before增強(qiáng)處理使用@Before標(biāo)注。通常需要通過一個(gè)value屬性,指定一個(gè)切入點(diǎn)表達(dá)式,用于指定該增強(qiáng)處理將被織入哪些切入點(diǎn)。@AspectpublicclassBeforeAdviceTest{//執(zhí)行l(wèi)ee包下所有類的、所有方法都將作為切入點(diǎn)@Before("execution(*lee.*.*(..))")publicvoidauthority(){System.out.println("模擬執(zhí)行權(quán)限檢查");}}

@ComponentpublicclassChineseimplementsPerson{publicStringsayHello(Stringname){returnname+"Hello,SpringAOP";}publicvoideat(Stringfood){System.out.println("我正在吃:"+food);}}該類可被無限地增強(qiáng)。3)After增強(qiáng)處理

使用@After標(biāo)注。常用屬性:

value:指定該增強(qiáng)處理被織入的切入點(diǎn)。與AfterReturing的區(qū)別:

AfterReturing增強(qiáng)處理只有在目標(biāo)方法成功完成后才會(huì)被織入,而After增強(qiáng)處理不管目標(biāo)方法如何完成(包括成功完成和遇到異常),它都會(huì)被織入。

例如:@AspectpublicclassAfterAdviceTest{//執(zhí)行l(wèi)ee包下所有類的、所有方法都將作為切入點(diǎn)@After("execution(*lee.*.*(..))")publicvoidrelease(){System.out.println("模擬方法結(jié)束后的釋放資源...");}}4)AfterReturning增強(qiáng)處理使用@AfterReturning標(biāo)注,將在目標(biāo)方法完成之后被織入。常用屬性:pointcut/value:用來指定該切入點(diǎn)對(duì)應(yīng)的切入點(diǎn)表達(dá)式。returning:指定一個(gè)返回值形參名,增強(qiáng)處理定義的方法可以通過該形參名來訪問目標(biāo)方法的返回值。例如:@AspectpublicclassAfterReturningAdviceTest{//執(zhí)行l(wèi)ee包下所有類的、所有方法都將作為切入點(diǎn)@AfterReturning(pointcut="execution(*lee.*.*(..))",returning="rvt")publicvoidlog(Object

rvt){System.out.println("獲取目標(biāo)方法返回值:"+rvt);System.out.println("模擬記錄日志功能...");}}5)定義AfterThrowing增強(qiáng)處理使用@AfterThrowing標(biāo)注,主要用于處理程序中未處理的異常。常用屬性:pointcut/value:指定該切入點(diǎn)對(duì)應(yīng)的切入表達(dá)式throwing:指定一個(gè)返回值形參名,增強(qiáng)處理定義的方法可以通過該形參名來訪問目標(biāo)方法中所拋出的異常對(duì)象。例如:@AspectpublicclassAfterThrowingAdviceTest{//執(zhí)行l(wèi)ee包下所有類的、所有方法都將作為切入點(diǎn)@AfterThrowing(pointcut="execution(*lee.*.*(..))",throwing="ex")publicvoiddoRecoveryActions(Throwableex){System.out.println("目標(biāo)方法中拋出的異常:"+ex);System.out.println("模擬拋出異常后的增強(qiáng)處理...");}}

AOP的AfterThrowing處理與結(jié)構(gòu)化異常處理的區(qū)別:catch捕捉意味著完全處理該異常,如果catch塊中沒有重新拋出新異常,則該方法可以正常結(jié)束。AfterThrowing處理雖然處理了該異常,但它不能完全處理該異常,該異常依然會(huì)向上傳播。6)Around增強(qiáng)處理

使用@Around標(biāo)注。

Around增強(qiáng)處理功能更加強(qiáng)大,近似于Before和AfterReturing增強(qiáng)處理的總和。與Before和AfterReturing增強(qiáng)處理不同的是:Around增強(qiáng)處理甚至可以決定目標(biāo)方法在什么時(shí)候被執(zhí)行,如何執(zhí)行,甚至可以完全阻止目標(biāo)方法的執(zhí)行。

Around增強(qiáng)處理可以改變執(zhí)行目標(biāo)方法的參數(shù)值,也可以改變執(zhí)行目標(biāo)方法之后的返回值。例如:@AspectpublicclassAroundAdviceTest{//執(zhí)行l(wèi)ee包下所有類的、所有方法都將作為切入點(diǎn)@Around("execution(*lee.*.*(..))")publicObjectprocessTx(ProceedingJoinPoint

jp)throwsjava.lang.Throwable{System.out.println("執(zhí)行目標(biāo)方法之前,模擬開始事務(wù)...");//執(zhí)行目標(biāo)方法,并保存目標(biāo)方法執(zhí)行后的返回值Objectrvt=ceed(newString[]{"被改變的參數(shù)"});System.out.println("執(zhí)行目標(biāo)方法之后,模擬結(jié)束事務(wù)...");returnrvt+"新增的內(nèi)容";}}

Around增強(qiáng)處理需要通過value屬性指定該增強(qiáng)處理被織入的切入點(diǎn)。當(dāng)定義Around增強(qiáng)處理方法時(shí),該方法的第一個(gè)參數(shù)必須時(shí)ProceedingJoinPoint類型,在增強(qiáng)處理方法體內(nèi),調(diào)用ProceedingJoinPoint的proceed()方法才會(huì)執(zhí)行目標(biāo)方法。調(diào)用proceed()時(shí),還可以傳入一個(gè)Object[]對(duì)象,該數(shù)組中的值將被傳入目標(biāo)方法作為執(zhí)行方法的實(shí)參。7)定義切入點(diǎn)

AspectJ和Spring都允許定義切入點(diǎn)。所謂定義切入點(diǎn),實(shí)質(zhì)就是為一個(gè)切入點(diǎn)表達(dá)式起一個(gè)名字,從而可以在多個(gè)增強(qiáng)處理中重用該名稱。切入點(diǎn)定義包括兩部分:一個(gè)切入點(diǎn)表達(dá)式一個(gè)包含名字和任意參數(shù)的方法簽名定義切入點(diǎn)使用@Pointcut標(biāo)注@AspectpublicclassSystemArchitecture

{@Pointcut("execution(*lee.Chin*.say*(..))")publicvoidmyPointcut(){}}

若需要使用該切入點(diǎn),則可在定義增強(qiáng)處理時(shí)使用pointcut參數(shù)。@AfterReturning(pointcut="SystemArchitecture.myPointcut()",returning="retVal")在下圖中展示了如何利用通配符,使多個(gè)切面同時(shí)使用一個(gè)定義。XML方式配置AOP1)定義切面使用<aop:aspect…/>元素??稍谠撛刂惺褂胷ef屬性為該切面Bean配置依賴注入。常用屬性:id:定義該切面的標(biāo)識(shí)名ref:指定引用的SpringBean作為切面Beanorder:指定切面Bean的優(yōu)先級(jí)2)配置增強(qiáng)處理使用XML配置增強(qiáng)處理使用以下幾個(gè)元素:<aop:before…/><aop:after…/><aop:after-

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論