版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、第3章 Spring的AOP模塊本章學(xué)習(xí)目的和要求本章重點和難點AOP是Spring框架的另一個重要特征。AOP(Aspect Oriented Programming,面向切面編程)把一個業(yè)務(wù)流程分成幾部分,例如權(quán)限檢查、業(yè)務(wù)處理、日志記錄,每個部分單獨處理,然后把它們組裝成完整的業(yè)務(wù)流程。每個部分被稱為切面(Aspect)或者關(guān)注點。3.1 實例:使用攔截器攔截方法(在struts-2.3.8中復(fù)制commons-logging-1.1.1、aopalliance-1.0.jar)AOP有一些重要的概念,包括切面(Aspect)、連接點(Joinpoint)、通知(Advice)、切入點(
2、Pointcut)、引用(Introduction)等。這些概念并不是Spring定義的。對于剛剛接觸AOP的開發(fā)者來說,這些概念非常抽象,往往很難理解。拋開這些抽象的概念,先來看一個AOP例子。前面的章節(jié)中曾介紹了一個AOP的例子。下面看一下稍微復(fù)雜的例子。本例中,AOP的規(guī)則要稍微復(fù)雜一些。3.1.1 Service接口Spring推薦使用接口編程。該接口定義了兩個方法。一會兒將使用攔截器攔截其中的withAop()方法,而另一個方法withoutAop()將不會被攔截。IAopService.javapackage com.helloweenvsfei.spring.aop;public
3、 interface IAopService/Service接口,定義兩個方法public void withAop() throws Exception;/將會被攔截public void withoutAop() throws Exception; /不會被攔截3.1.2 Service實現(xiàn)代碼IAopService實現(xiàn)類中定義了一個name屬性,以及對應(yīng)的getter、setter方法。實現(xiàn)類代碼為:AopServiceImpl.javapackage com.helloweenvsfei.spring.aop;import javax.security.auth.login.Accou
4、ntException;public class AopServiceImpl implements IAopService/Service實現(xiàn)private String name;/name屬性public void withAop() throws Exception/withAop方法實現(xiàn)System.out.println("有AOP的函數(shù)運行。name: "+name);if (name.trim().length()=0)/ 如果name為空throw new AccountException("name屬性不能為空"); / 則拋出異常p
5、ublic void withoutAop() throws Exception/ withoutAop方法實現(xiàn)System.out.println("沒有AOP的函數(shù)運行。");public String getName()/getter方法return name;public void setName(String name)/setter方法=name;3.1.3 方法前攔截器檢查name是否為null下面是方法前攔截器,實現(xiàn)自MethodBeforeAdvice接口。方法前攔截器在執(zhí)行指定方法前被調(diào)用,參數(shù)分別為被調(diào)用的方法、執(zhí)行時被傳入的參數(shù)、被
6、攔截的Bean。代碼為:MethodBeforeInterceptor.javapackage com.helloweenvsfei.spring.aop;import java.lang.reflect.Method;import org.springframework.aop.MethodBeforeAdvice;public class MethodBeforeInterceptor implements MethodBeforeAdvice/方法前攔截器/ 調(diào)用對象的方法前將執(zhí)行該方法。參數(shù)分別為被調(diào)用的方法、被調(diào)用調(diào)用方法的參數(shù)、對象public void before(Method
7、 method, Object args, Object instance) throws ThrowableSystem.out.println("即將要執(zhí)行方法:" + method.getName();/ 打印控制臺if(instance instanceof AopServiceImpl)/如果是ServiceString name=(AopServiceImpl) instance).getName();/ 獲取nameif(name=null)/ 檢查是否為空throw new NullPointerException("name屬性不能為null&q
8、uot;);3.1.4 返回后攔截器輸出返回值返回后攔截器,實現(xiàn)自AfterReturningAdvice接口。返回后攔截器在執(zhí)行完指定方法、并返回之后被調(diào)用。如果有返回值,可以取到返回值,否則為null。參數(shù)分別為方法返回值、被調(diào)用的方法、執(zhí)行時被傳入的參數(shù)、被攔截的Bean。代碼為:MethodAfterInterceptor.javapackage com.helloweenvsfei.spring.aop;import java.lang.reflect.Method;import org.springframework.aop.AfterReturningAdvice;public
9、class MethodAfterInterceptor implements AfterReturningAdvice/方法后攔截器public void afterReturning(Object value, Method method, Object args,Object instance) throws ThrowableSystem.out.println("方法"+method.getName()+"運行完畢,返回值為:"+value);3.1.5 異常攔截器捕獲異常異常拋出攔截器,實現(xiàn)自ThrowsAdvice接口。如果指定的方法中有異
10、常被拋出,被調(diào)用。與上兩個攔截器接口不同,ThrowsAdvice接口沒有定義任何方法,因此不需要實現(xiàn)任何方法。但是如果定義了形如afterThrowing(Method,args,target,subclassOfThrowable)的方法,這些方法將會被調(diào)用。參數(shù)分別為:被調(diào)用的方法、方法的參數(shù)、被攔截的Bean以及拋出的異常類。這里面只有最后一個參數(shù)是必須的。Spring之所以這樣設(shè)計,是為了是開發(fā)者靈活的定義多個方法捕捉不同的異常。代碼為:package com.helloweenvsfei.spring.aop;import java.lang.reflect.Method; imp
11、ort javax.security.auth.login.AccountException;import org.springframework.aop.ThrowsAdvice;public class ThrowsInterceptor implements ThrowsAdvice/異常攔截器public void afterThrowing(Method method, Object args, Object instance,AccountException ex) throws ThrowableSystem.out.println("方法"+method.g
12、etName()+" 拋出了異常:"+ex);public void afterThrowing(NullPointerException ex) throws ThrowableSystem.out.println("拋出了異常:" + ex);3.1.6 攔截器配置然后把三個攔截器連同Service實現(xiàn)類配置到Spring中。Spring將實例化三個攔截器對象、一個Service對象,并安裝指定的規(guī)則裝配。配置代碼為:ApplicationContext.xml<?xml version="1.0" encoding=&qu
13、ot;UTF-8"?><beans xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="/schema/beans /schema/beans/spring-beans-2.0.xsd"><!-攔截
14、器 在withAop()方法前運行-><bean id="aopMethodBeforeInterceptor" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor"><property name="advice"><bean class="com.helloweenvsfei.spring.aop.MethodBeforeInterceptor" /></property>
15、<property name="mappedName" value="withAop"></property></bean><!- 攔截器 在 withAop() 返回后運行 -><bean id="aopMethodAfterInterceptor"class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor"><property name="advice&qu
16、ot;><bean class="com.helloweenvsfei.spring.aop.MethodAfterInterceptor" /></property><property name="mappedName" value="withAop"></property></bean><!- 攔截器 在異常拋出后運行 -><bean id="aopThrowsInterceptor"class="org.spring
17、framework.aop.support.NameMatchMethodPointcutAdvisor"><property name="advice"><bean class="com.helloweenvsfei.spring.aop.ThrowsInterceptor" /></property><property name="mappedName" value="withAop"></property></bean>&
18、lt;bean id="aopService"class="org.springframework.aop.framework.ProxyFactoryBean"><!- 攔截器 -><property name="interceptorNames"><list><value>aopMethodBeforeInterceptor</value><value>aopMethodAfterInterceptor</value><value>
19、;aopThrowsInterceptor</value></list></property><!- 被攔截的對象 -><property name="target"><bean class="com.helloweenvsfei.spring.aop.AopServiceImpl"><property name="name" value="Helloween"></property></bean></
20、property></bean></beans>3.1.7 運行代碼運行代碼從Spring容器中獲取Service對象,并分別執(zhí)行Service的兩個方法withAop()與withoutAop()。Spring將會在withAop()方法前后添加攔截器,但withoutAop()方法前后不會。代碼為:AopRun.javapackage com.helloweenvsfei.spring.aop;import org.springframework.beans.factory.xml.XmlBeanFactory;import org.springframewo
21、rk.core.io.ClassPathResource;public class AopRunpublic static void main(String args) throws Exception XmlBeanFactory factory = new XmlBeanFactory(/獲取Factorynew ClassPathResource("applicationContext.xml");IAopService hello = (IAopService) factory.getBean("aopService");/ 查找對象hello.
22、withAop();/ 執(zhí)行withAop()hello.withoutAop();/ 執(zhí)行withoutAop()factory.destroySingletons();/ 銷毀對象運行效果如圖3.1。圖3.1 攔截器運行效果在本例中,由于沒有異常拋出,因此ThrowsInterceptor沒有起作用。讀者可以在xml中設(shè)置name屬性為null或者空字符串,使withAop()方法中拋出異常,觀察運行效果。3.2 攔截器與Filter的區(qū)別Spring的攔截器與Servlet的Filter有相似之處,比如二者都是AOP編程思想的體現(xiàn),都能實現(xiàn)權(quán)限檢查、日志記錄等。不同的是:3.2.1 使用
23、范圍不同F(xiàn)ilter是Servlet規(guī)范規(guī)定的,只能用于Web程序中。而攔截器即可以用于Web程序,也可以用于Application、Swing程序中。3.2.2 規(guī)范不同F(xiàn)ilter是在Servlet規(guī)范中定義的,是Servlet容器支持的。而攔截器是在Spring容器內(nèi)的,是Spring框架支持的。3.2.3 使用的資源不同同其它的代碼塊一樣,攔截器也是一個Spring的組件,歸Spring管理,配置在Spring文件中,因此能使用Spring里的任何資源、對象,例如Service對象、數(shù)據(jù)源、事務(wù)管理等,通過IoC注入到攔截器即可;而Filter則不能。3.2.4 深度不同F(xiàn)ilter在
24、只在Servlet前后起作用。而攔截器能夠深入到方法前后、異常拋出前后等,因此攔截器的使用具有更大的彈性。因此在Spring構(gòu)架的程序中,要優(yōu)先使用攔截器。3.3 AOP的相關(guān)概念看一下面向切面的編程的幾個常用的概念:切面Aspect、通知Advisor與切入點Pointcut。3.3.1 切面Aspect在本例中,方法withAop()、withoutAop()中都有一些代碼。雖然只是一些輸出語句,但是在真實的程序中這里應(yīng)該是一些有意義的代碼(如讀寫數(shù)據(jù)庫、權(quán)限檢查、異常情況記錄等)。這些代碼可以看作是AOP中的切面(Aspect)。可以將切面理解為模塊。3.2.2 通知Advisor本例的
25、三個攔截器都是實現(xiàn)自某個Advisor接口。從類名上看就知道三個攔截器都是AOP中的通知(Advisor)。一旦Spring符合條件,就會派發(fā)出通知。與生活中的通知不同的地方在于,Spring中的通知是帶有執(zhí)行代碼的,實現(xiàn)某種功能。3.3.3 切入點Pointcut在配置攔截器的時候,xml中只配置了withAop()方法使用攔截器,而withoutAop()方法沒有配置攔截器。這種配置是借助于org.springframework.aop.support.NameMatchMethodPointcutAdvisor完成的。從類名稱上看,這是一個切入點(Pointcut)。該類對象能配置對哪些
26、方法使用攔截器,從哪個地方“切入”進去。配置時可以使用通配符。該類名上也帶有Advisor是因為它是用通知(Advisor)實現(xiàn)的。簡單地說,“切入點”負責(zé)往“什么地方”插入代碼,而“通知”負責(zé)插入“什么代碼”。3.3.4 切入點配置方式Spring提供靈活的切入點配置方式。例如使用正則表達式。下面是Spring官方的一個使用正則表達式的例子。Spring接受Perl 5支持的正則表達式:<bean id="settersAndAbsquatulateAdvisor" class="org.springframework.aop.support.Regexp
27、MethodPointcutAdvisor"><!-切入點-> <property name="interceptor"> <ref local="beanNameOfAopAllianceInterceptor"/><!-攔截器-> </property> <property name="patterns"><!-正則表達式配置切入點-> <list> <value>.*get.*</value>&
28、lt;!-包含get的方法-> <value>.*absquatulate</value><!-包含absquatulate的方法-> </list> </property></bean>3.4 AOP的代理模式代理模式是Spring中常用的設(shè)計模式。Spring提供了幾個常用的代理類,例如普通的代理類、事務(wù)代理類等等。3.4.1 ProxyFactoryBean代理工廠對象上例配置AopServiceImpl時使用了org.springframework.aop.framework.ProxyFactoryBean類。這是Spring內(nèi)置的代理類,引入了一個中間層,能夠創(chuàng)建不同類型的對象。利用它可以實現(xiàn)任何形式的AOP。3.4.2 TransactionProxyFactoryBean事務(wù)代理工廠對象另一個很有用的代理類是TransactionProxyFactoryBean,是ProxyFactoryBean的子類,常用在數(shù)據(jù)庫編程上。Spring利用TransactionProxyFactoryBean對事務(wù)進行管理,在指定方法前利用AOP連接數(shù)據(jù)庫并開啟事務(wù),然后在指定方法返回后利用AOP提交事務(wù)并斷開數(shù)據(jù)庫。例如Spring寵物商店里的事務(wù)性配置:<bean
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024美容院業(yè)務(wù)外包管理合同
- 鄭州工程技術(shù)學(xué)院《Photoshop圖像處理B(實驗)》2023-2024學(xué)年第一學(xué)期期末試卷
- 鄭州電力職業(yè)技術(shù)學(xué)院《護理專業(yè)英語》2023-2024學(xué)年第一學(xué)期期末試卷
- 鄭州城市職業(yè)學(xué)院《中外媒介史》2023-2024學(xué)年第一學(xué)期期末試卷
- 鄭州財經(jīng)學(xué)院《二維動畫設(shè)計》2023-2024學(xué)年第一學(xué)期期末試卷
- 鎮(zhèn)江市高等專科學(xué)?!稊?shù)字系統(tǒng)與邏輯設(shè)計》2023-2024學(xué)年第一學(xué)期期末試卷
- 浙江越秀外國語學(xué)院《營養(yǎng)與健康》2023-2024學(xué)年第一學(xué)期期末試卷
- 2025版寵物寄養(yǎng)服務(wù)與寵物美容合作合同范本3篇
- 2025年度半導(dǎo)體器件加工與可靠性測試協(xié)議3篇
- 二零二五年機房建設(shè)與運維一體化施工合同書3篇
- 2024-2030年中國食品飲料灌裝設(shè)備行業(yè)市場發(fā)展趨勢與前景展望戰(zhàn)略分析報告
- 建筑結(jié)構(gòu)課程設(shè)計成果
- 班級建設(shè)方案中等職業(yè)學(xué)校班主任能力大賽
- 纖維增強復(fù)合材料 單向增強材料Ⅰ型-Ⅱ 型混合層間斷裂韌性的測定 編制說明
- 習(xí)近平法治思想概論教學(xué)課件緒論
- 寵物會展策劃設(shè)計方案
- 孤殘兒童護理員(四級)試題
- 醫(yī)院急診醫(yī)學(xué)小講課課件:急診呼吸衰竭的處理
- 腸梗阻導(dǎo)管在臨床中的使用及護理課件
- 小學(xué)英語單詞匯總大全打印
- 衛(wèi)生健康系統(tǒng)安全生產(chǎn)隱患全面排查
評論
0/150
提交評論