生活随笔
收集整理的這篇文章主要介紹了
Spring3.0 AOP 详解
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
一、什么是 AOP。 AOP(Aspect Orient Programming),也就是面向切面編程 。可以這樣理解,面向?qū)ο缶幊?#xff08;OOP)是從靜態(tài)角度考慮程序結(jié)構(gòu),面向切面編程(AOP)是從動態(tài)角度考慮程序運(yùn)行過程 。
?
二、AOP 的作用。 常常通過 AOP 來處理一些具有橫切性質(zhì)的系統(tǒng)性服務(wù) ,如事物管理、安全檢查、緩存、對象池管理 等,AOP 已經(jīng)成為一種非常常用的解決方案。
?
三、AOP 的實(shí)現(xiàn)原理。
如圖:AOP 實(shí)際上是由目標(biāo)類的代理類實(shí)現(xiàn)的 。AOP 代理其實(shí)是由 AOP 框架動態(tài)生成的一個(gè)對象,該對象可作為目標(biāo)對象使用 。AOP 代理包含了目標(biāo)對象的全部方法,但 AOP 代理中的方法與目標(biāo)對象的方法存在差異,AOP 方法在特定切入點(diǎn)添加了增強(qiáng)處理,并回調(diào)了目標(biāo)對象的方法 。
?
四、Spring 中對 AOP 的支持 Spring 中 AOP 代理由 Spring 的 IoC 容器負(fù)責(zé)生成、管理,其依賴關(guān)系也由 IoC 容器負(fù)責(zé)管理 。因此,AOP 代理可以直接使用容器中的其他 Bean 實(shí)例作為目標(biāo),這種關(guān)系可由 IoC 容器的依賴注入提供。Spring 默認(rèn)使用 Java 動態(tài)代理來創(chuàng)建 AOP 代理 , 這樣就可以為任何接口實(shí)例創(chuàng)建代理了。當(dāng)需要代理的類不是代理接口的時(shí)候,?Spring 自動會切換為使用 CGLIB 代理,也可強(qiáng)制使用 CGLIB 。?
AOP 編程其實(shí)是很簡單的事情??v觀 AOP 編程, 其中需要程序員參與的只有三個(gè)部分:
?
定義普通業(yè)務(wù)組件。 定義切入點(diǎn),一個(gè)切入點(diǎn)可能橫切多個(gè)業(yè)務(wù)組件。 定義增強(qiáng)處理,增強(qiáng)處理就是在 AOP 框架為普通業(yè)務(wù)組件織入的處理動作。 ?
所以進(jìn)行 AOP 編程的關(guān)鍵就是定義切入點(diǎn)和定義增強(qiáng)處理。一旦定義了合適的切入點(diǎn)和增強(qiáng)處理,AOP 框架將會自動生成 AOP 代理,即:代理對象的方法 = 增強(qiáng)處理 + 被代理對象的方法 。
?
五、Spring 中 AOP 的實(shí)現(xiàn)。 Spring 有如下兩種選擇來定義切入點(diǎn)和增強(qiáng)處理。
?
基于 Annotation 的“零配置”方式:使用@Aspect、@Pointcut等 Annotation 來標(biāo)注切入點(diǎn)和增強(qiáng)處理。 基于 XML 配置文件的管理方式:使用 Spring 配置文件來定義切入點(diǎn)和增強(qiáng)點(diǎn)。 ?
1、基于 Annotation 的“零配置”方式。 (1)、首先啟用 Spring 對 @AspectJ 切面配置的支持。 ?
[java] ?view plaincopy
<?xml?version="1.0"?encoding="UTF-8"?>?? <beans?xmlns="http://www.springframework.org/schema/beans"?? ???????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"?? ???????xmlns:aop="http://www.springframework.org/schema/aop"???????? ???????xsi:schemaLocation="http: ???????????http: ???????????http: ???????http: ????????<!--?啟動對@AspectJ注解的支持?-->?? ????????<aop:aspectj-autoproxy/>?? </beans>?? 如果不打算使用 Spring 的 XML Schema 配置方式,則應(yīng)該在 Spring 配置文件中增加如下片段來啟用@AspectJ 支持。
?
?
[java] ?view plaincopy
<!--?啟用@AspectJ?支持?-->?? <bean?class="org.springframeword.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator"?/>?? ?
?
(2)、定義切面 Bean。 當(dāng)啟動了@AspectJ 支持后,只要在 Spring 容器中配置一個(gè)帶@Aspect 注釋的 Bean, Spring 將會自動識別該 Bean 并作為切面處理。
?
[java] ?view plaincopy
@Aspect?? public?class?LogAspect?{?? ???????? ????????...?? }?? ?
?
(3)、定義 Before 增強(qiáng)處理。 ?
?
[java] ?view plaincopy
@Aspect?? public?class?BeforeAdviceTest?{?? ???? ????@Before("execution(*?com.wicresoft.app.service.impl.*.*(..))")?? ????public?void?authorith(){?? ????????System.out.println("模擬進(jìn)行權(quán)限檢查。");?? ????}?? }?? ?
?
上面使用@Before Annotation 時(shí),直接指定了切入點(diǎn)表達(dá)式,指定匹配?com.wicresoft.app.service.impl包下所有類的所有方法執(zhí)行作為切入點(diǎn)。 關(guān)于這個(gè)表達(dá)式的規(guī)則如下圖。
?
(4)、定義 AfterReturning 增強(qiáng)處理。 ?
[java] ?view plaincopy
@Aspect?? public?class?AfterReturningAdviceTest?{?? ???? ????@AfterReturning(returning="rvt",?pointcut="execution(*?com.wicresoft.app.service.impl.*.*(..))")?? ????public?void?log(Object?rvt)?{?? ????????System.out.println("模擬目標(biāo)方法返回值:"?+?rvt);?? ????????System.out.println("模擬記錄日志功能...");?? ????}?? }?? ?
?
(5)、定義 AfterThrowing 增強(qiáng)處理。 ?
?
[java] ?view plaincopy
@Aspect?? public?class?AfterThrowingAdviceTest?{?? ???? ????@AfterThrowing(throwing="ex",?pointcut="execution(*?com.wicresoft.app.service.impl.*.*(..))")?? ????public?void?doRecoverActions(Throwable?ex)?{?? ????????System.out.println("目標(biāo)方法中拋出的異常:"?+?ex);?? ????????System.out.println("模擬拋出異常后的增強(qiáng)處理...");?? ????}?? }?? ?
?
(6)、定義 After 增強(qiáng)處理。 ?
After 增強(qiáng)處理與AfterReturning?增強(qiáng)處理有點(diǎn)相似,但也有區(qū)別:
?
AfterReturning?增強(qiáng)處理處理只有在目標(biāo)方法成功完成后才會被織入。 After 增強(qiáng)處理不管目標(biāo)方法如何結(jié)束(保存成功完成和遇到異常中止兩種情況),它都會被織入。 ?
?
[java] ?view plaincopy
@Aspect?? public?class?AfterAdviceTest?{?? ???? ????@After("execution(*?com.wicresoft.app.service.impl.*.*(..))")?? ????public?void?release()?{?? ????????System.out.println("模擬方法結(jié)束后的釋放資源...");?? ????}?? }?? ?
?
(7)、Around 增強(qiáng)處理 ?
Around 增強(qiáng)處理近似等于 Before 增強(qiáng)處理和 ?AfterReturning 增強(qiáng)處理的總和。它可改變執(zhí)行目標(biāo)方法的參數(shù)值,也可改變目標(biāo)方法之后的返回值。
?
[java] ?view plaincopy
@Aspect?? public?class?AroundAdviceTest?{?? ???? ????@Around("execution(*?com.wicresoft.app.service.impl.*.*(..))")?? ????public?Object?processTx(ProceedingJoinPoint?jp)?throws?java.lang.Throwable?{?? ????????System.out.println("執(zhí)行目標(biāo)方法之前,模擬開始事物...");?? ???????? ????????Object?rvt?=?jp.proceed(new?String[]{"被改變的參數(shù)"});?? ????????System.out.println("執(zhí)行目標(biāo)方法之前,模擬結(jié)束事物...");?? ????????return?rvt?+?"新增的內(nèi)容";?? ????}?? }?? ?
?
(8)、訪問目標(biāo)方法的參數(shù)。 ?
訪問目標(biāo)方法最簡單的做法是定義增強(qiáng)處理方法時(shí)將第一個(gè)參數(shù)定義為 JoinPoint 類型,當(dāng)該增強(qiáng)處理方法被調(diào)用時(shí),該 JoinPoint 參數(shù)就代表了織入增強(qiáng)處理的連接點(diǎn)。JoinPoint 里包含了如下幾個(gè)常用方法。
?
Object[] getArgs(): 返回執(zhí)行目標(biāo)方法時(shí)的參數(shù)。 Signature getSignature(): 返回被增強(qiáng)的方法的相關(guān)信息。 Object getTarget(): 返回被織入增強(qiáng)處理的目標(biāo)對象。 Object getThis(): 返回 AOP 框架為目標(biāo)對象生成的代理對象。 ?
提示:當(dāng)時(shí)使用 Around 處理時(shí),我們需要將第一個(gè)參數(shù)定義為 ProceedingJoinPoint 類型,該類型是 JoinPoint 類型的子類 。
?
(9)、定義切入點(diǎn)。 所謂切入點(diǎn),其實(shí)質(zhì)就是為一個(gè)切入點(diǎn)表達(dá)式起一個(gè)名稱,從而允許在多個(gè)增強(qiáng)處理中重用該名稱。
Spring 切入點(diǎn)定義包含兩個(gè)部分:
?
一個(gè)切入點(diǎn)表達(dá)式。 一個(gè)包含名字和任意參數(shù)的方法簽名。 ?
?
[java] ?view plaincopy
@pointcut("execution?*?transfer(..)")?? private?void?anyOldTransfer(){}?? ?? @AfterReturning(pointcut="anyOldTransfer()",?returning="reVal")?? public?void?writeLog(String?msg,?Object?reVal){?? ????...?? }?? ?
?
2、基于 XML 配置文件的管理方式。 ?
?
?
?
[java] ?view plaincopy
<?xml?version="1.0"?encoding="UTF-8"?>?? <beans?xmlns="http://www.springframework.org/schema/beans"?? ???????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"?? ???????xmlns:aop="http://www.springframework.org/schema/aop"???????? ???????xsi:schemaLocation="http: ???????????http: ???????????http: ???????http: ????????<aop:config>?? ????????????<!--?將?fourAdviceBean?轉(zhuǎn)換成切面?Bean,?切面?Bean?的新名稱為:fourAdviceAspect,指定該切面的優(yōu)先級為2?-->?? ????????????<aop:aspect?id="fourAdviceAspect"?ref="fourAdviceBean"?order="2">?? ????????????????<!--?定義個(gè)After增強(qiáng)處理,直接指定切入點(diǎn)表達(dá)式,以切面?Bean?中的?Release()?方法作為增強(qiáng)處理方法?-->?? ????????????????<aop:after?pointcut="execution(*?com.wicresoft.app.service.impl.*.*(..))"?method="release"?/>?? ?????????????????? ????????????????<!--?定義個(gè)Before增強(qiáng)處理,直接指定切入點(diǎn)表達(dá)式,以切面?Bean?中的?authority()?方法作為增強(qiáng)處理方法?-->?? ????????????????<aop:before?pointcut="execution(*?com.wicresoft.app.service.impl.*.*(..))"?method="authority"?/>?? ?????????????????? ????????????????<!--?定義個(gè)AfterReturning增強(qiáng)處理,直接指定切入點(diǎn)表達(dá)式,以切面?Bean?中的?log()?方法作為增強(qiáng)處理方法?-->?? ????????????????<aop:after-returning?pointcut="execution(*?com.wicresoft.app.service.impl.*.*(..))"?method="log"?/>?? ?????????????????? ????????????????<!--?定義個(gè)Around增強(qiáng)處理,直接指定切入點(diǎn)表達(dá)式,以切面?Bean?中的?processTx()?方法作為增強(qiáng)處理方法?-->?? ????????????????<aop:around?pointcut="execution(*?com.wicresoft.app.service.impl.*.*(..))"?method="processTx"?/>?? ?????????????????? ????????????</aop:aspect>?? ????????</aop:config>?? ?????????? ????????<!--?省略各個(gè)Bean?的配置?-->?? ????????<!--?...?-->?? ?????????? </beans>?? ?
?
?
?
[java] ?view plaincopy
<?xml?version="1.0"?encoding="UTF-8"?>?? <beans?xmlns="http://www.springframework.org/schema/beans"?? ???????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"?? ???????xmlns:aop="http://www.springframework.org/schema/aop"???????? ???????xsi:schemaLocation="http: ???????????http: ???????????http: ???????http: ????????<aop:config>?? ????????????<!--?定義一個(gè)切入點(diǎn),myPointcut,直接知道它對應(yīng)的切入點(diǎn)表達(dá)式?-->?? ????????????<aop:pointcut?id="myPointcut"?expression="execution(*?com.wicresoft.app.service.impl.*.*(..))"?method="release"?/>?? ????????????<aop:aspect?id="afterThrowingAdviceAspect"?ref="afterThrowingAdviceBean"?order="1">?? ????????????????<!--?使用上面定于切入點(diǎn)定義增強(qiáng)處理?-->?? ????????????????<!--?定義一個(gè)AfterThrowing?增強(qiáng)處理,指定切入點(diǎn)以切面?Bean?中的?doRecovertyActions()?方法作為增強(qiáng)處理方法?-->?? ????????????????<aop:after-throwing?pointcut-ref="myPointcut"?method="doRecovertyActions"?throwing="ex"?/>?? ????????????</aop:aspect>?? ????????</aop:config>?? ?????????? ????????<!--?省略各個(gè)Bean?的配置?-->?? ????????<!--?...?-->?? ?????????? </beans> ? ?
原文件引用地址:http://blog.csdn.net/a906998248/article/details/7514969#t6
總結(jié)
以上是生活随笔 為你收集整理的Spring3.0 AOP 详解 的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔 推薦給好友。