Spring AOP原理及攔截器_第1頁(yè)
Spring AOP原理及攔截器_第2頁(yè)
Spring AOP原理及攔截器_第3頁(yè)
Spring AOP原理及攔截器_第4頁(yè)
Spring AOP原理及攔截器_第5頁(yè)
已閱讀5頁(yè),還剩23頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、原理AOP(Aspect Oriented Programming),也就是面向方面編程的技術(shù)。AOP基于IoC基礎(chǔ),是對(duì)OOP的有益補(bǔ)充。AOP將應(yīng)用系統(tǒng)分為兩部分,核心業(yè)務(wù)邏輯(Core business concerns)及橫向的通用邏輯,也就是所謂的方面Crosscutting enterprise concerns,例如,所有大中型應(yīng)用都要涉及到的持久化管理(Persistent)、事務(wù)管理(Transaction Management)、安全管理(Security)、日志管理(Logging)和調(diào)試管理(Debugging)等。AOP正在成為軟件開(kāi)發(fā)的下一個(gè)光環(huán)。使用AOP,你可以

2、將處理aspect的代碼注入主程序,通常主程序的主要目的并不在于處理這些aspect。AOP可以防止代碼混亂。Spring framework是很有前途的AOP技術(shù)。作為一種非侵略性的、輕型的AOP framework,你無(wú)需使用預(yù)編譯器或其他的元標(biāo)簽,便可以在Java程序中使用它。這意味著開(kāi)發(fā)團(tuán)隊(duì)里只需一人要對(duì)付AOP framework,其他人還是像往常一樣編程。AOP概念讓我們從定義一些重要的AOP概念開(kāi)始。 方面(Aspect):一個(gè)關(guān)注點(diǎn)的模塊化,這個(gè)關(guān)注點(diǎn)實(shí)現(xiàn)可能另外橫切多個(gè)對(duì)象。事務(wù)管理是J2EE應(yīng)用中一個(gè)很好的橫切關(guān)注點(diǎn)例子。方面用Spring的Advisor或攔截器實(shí)現(xiàn)。 連

3、接點(diǎn)(Joinpoint):程序執(zhí)行過(guò)程中明確的點(diǎn),如方法的調(diào)用或特定的異常被拋出。 通知(Advice):在特定的連接點(diǎn),AOP框架執(zhí)行的動(dòng)作。各種類(lèi)型的通知包括“around”、“before”和“throws”通知。通知類(lèi)型將在下面討論。許多AOP框架包括Spring都是以攔截器做通知模型,維護(hù)一個(gè)“圍繞”連接點(diǎn)的攔截器鏈。 切入點(diǎn)(Pointcut):指定一個(gè)通知將被引發(fā)的一系列連接點(diǎn)的集合。AOP框架必須允許開(kāi)發(fā)者指定切入點(diǎn),例如,使用正則表達(dá)式。 引入(Introduction):添加方法或字段到被通知的類(lèi)。Spring允許引入新的接口到任何被通知的對(duì)象。例如,你可以使用一個(gè)引入使

4、任何對(duì)象實(shí)現(xiàn)IsModified接口,來(lái)簡(jiǎn)化緩存。 目標(biāo)對(duì)象(Target Object):包含連接點(diǎn)的對(duì)象,也被稱(chēng)作被通知或被代理對(duì)象。 AOP代理(AOP Proxy):AOP框架創(chuàng)建的對(duì)象,包含通知。在Spring中,AOP代理可以是JDK動(dòng)態(tài)代理或CGLIB代理。 編織(Weaving):組裝方面來(lái)創(chuàng)建一個(gè)被通知對(duì)象。這可以在編譯時(shí)完成(例如使用AspectJ編譯器),也可以在運(yùn)行時(shí)完成。Spring和其他純Java AOP框架一樣,在運(yùn)行時(shí)完成織入。各種通知類(lèi)型包括:  Around通知:包圍一個(gè)連接點(diǎn)的通知,如方法調(diào)用。這是最強(qiáng)大的通知。Aroud通知在方法調(diào)用前后完成自

5、定義的行為,它們負(fù)責(zé)選擇繼續(xù)執(zhí)行連接點(diǎn)或通過(guò)返回它們自己的返回值或拋出異常來(lái)短路執(zhí)行。  Before通知:在一個(gè)連接點(diǎn)之前執(zhí)行的通知,但這個(gè)通知不能阻止連接點(diǎn)前的執(zhí)行(除非它拋出一個(gè)異常)。  Throws通知:在方法拋出異常時(shí)執(zhí)行的通知。Spring提供強(qiáng)制類(lèi)型的Throws通知,因此你可以書(shū)寫(xiě)代碼捕獲感興趣的異常(和它的子類(lèi)),不需要從Throwable或Exception強(qiáng)制類(lèi)型轉(zhuǎn)換。  After returning通知:在連接點(diǎn)正常完成后執(zhí)行的通知,例如,一個(gè)方法正常返回,沒(méi)有拋出異常。Around通知是最通用的通知類(lèi)型。大部分基于攔截的AOP框架(如

6、Nanning和Jboss 4)只提供Around通知。如同AspectJ,Spring提供所有類(lèi)型的通知,我們推薦你使用最 為合適的通知類(lèi)型來(lái)實(shí)現(xiàn)需要的行為。例如,如果只是需要用一個(gè)方法的返回值來(lái)更新緩存,你最好實(shí)現(xiàn)一個(gè)after returning通知,而不是around通知,雖然around通知也能完成同樣的事情。使用最合適的通知類(lèi)型使編程模型變得簡(jiǎn)單,并能減少潛在錯(cuò) 誤。例如,你不需要調(diào)用在around通知中所需使用的MethodInvocation的proceed()方法,因此就調(diào)用失敗。切入點(diǎn)的概念是AOP的關(guān)鍵,它使AOP區(qū)別于其他使用攔截的技術(shù)。切入點(diǎn)使通知獨(dú)立于OO的層次選定

7、目標(biāo)。例如,提供聲明式事務(wù)管理的around通知可以被應(yīng)用到跨越多個(gè)對(duì)象的一組方法上。 因此切入點(diǎn)構(gòu)成了AOP的結(jié)構(gòu)要素。 攔截器(也稱(chēng)攔截機(jī))    攔截機(jī) (Interceptor), 是 AOP (Aspect-Oriented Programming) 的另一種叫法。AOP本身是一門(mén)語(yǔ)言,只不過(guò)我們使用的是基于JAVA的集成到Spring 中的 SpringAOP。同樣,我們將通過(guò)我們的例子來(lái)理解陌生的概念。   接口類(lèi)Java代碼  1. <span style="font-size:&#

8、160;medium;">package com.test.TestSpring3;  2.   3. public interface UserService / 被攔截的接口  4. .  5.     public void printUser(String user);  6.   7. </span> 

9、0; 實(shí)現(xiàn)類(lèi)Java代碼  1. <span style="font-size: medium;">package com.test.TestSpring3;  2.   3. public class UserServiceImp implements UserService / 實(shí)現(xiàn)UserService接口  4. .  5.    

10、60;public void printUser(String user) .  6.         System.out.println("printUser user:" + user);/ 顯示user  7.       8.   9.   10. </span&

11、gt;   AOP攔截器Java代碼  1. <span style="font-size: medium;">package com.test.TestSpring3;  2.   3. import ercept.MethodInterceptor;  4. import ercept.MethodInvocation; &#

12、160;5.   6. public class UserInterceptor implements MethodInterceptor  7. / AOP方法攔截器  8. .  9.   10.     public Object invoke(MethodInvocation arg0) throws Throwable . &#

13、160;11.   12.         try .  13.   14.             if (arg0.getMethod().getName().equals("printUser")  15.      

14、60;      / 攔截方法是否是UserService接口的printUser方法  16.             .  17.                 Object args 

15、;= arg0.getArguments();/ 被攔截的參數(shù)  18.                 System.out.println("user:" + args0);  19.             

16、60;   arg0.getArguments()0 = "hello!"/ 修改被攔截的參數(shù)  20.   21.               22.   23.             Syste

17、m.out.println(arg0.getMethod().getName() + "-!");  24.             return ceed();/ 運(yùn)行UserService接口的printUser方法  25.   26.         &#

18、160;catch (Exception e) .  27.             throw e;  28.           29.       30.   31. </span><span&#

19、160;style="font-size: medium;">  32. </span>   測(cè)試類(lèi)Java代碼  1. <span style="font-size: medium;">package com.test.TestSpring3;  2.   3. import org.springframework.beans.factory.BeanFactory;

20、0; 4.   5. import org.springframework.beans.factory.xml.XmlBeanFactory;  6. import org.springframework.context.ApplicationContext;  7. import org.springframework.context.support.ClassPathXmlApplicationContext;  8. import org.springfram

21、ework.context.support.FileSystemXmlApplicationContext;  9. import org.springframework.core.io.ClassPathResource;  10. import org.springframework.core.io.Resource;  11. import org.springframework.web.context.support.WebApplicationContextUtils;  1

22、2.   13. public class TestInterceptor .  14.   15.     public static void main(String args) .  16.         ApplicationContext ctx = new File

23、SystemXmlApplicationContext(  17.                 "classpath:applicationContext.xml");  18. /        ApplicationContext ctx = new 

24、ClassPathXmlApplicationContext("applicationContext.xml");      19.           20.         UserService us = (UserService) ctx.getBean("userService&

25、quot;);  21.         us.printUser("shawn");  22.   23.       24. </span><span style="font-size: medium;">  25. </span>   配置文件&#

26、160;   Xml代碼  1. <span style="font-size: medium;"><?xml version="1.0" encoding="UTF-8"?>  2. <!DOCTYPE beans PUBLIC "-/SPRING/DTD BEAN/EN" "/

27、dtd/spring-beans.dtd">  3. <beans>  4.     <bean id="userServiceImp"  5.         class="com.test.TestSpring3.UserServiceImp" />  6.   7. 

28、60;   <bean id="userInterceptor" class="com.test.TestSpring3.UserInterceptor" />  8.   9.     <bean id="userService"  10.         class=

29、"org.springframework.aop.framework.ProxyFactoryBean">  11.       <!- 代理接口 ->  12.         <property name="proxyInterfaces">  13.    

30、60;        <value>com.test.TestSpring3.UserService</value>  14.         </property>  15.        <!- 目標(biāo)實(shí)現(xiàn)類(lèi) ->  16.  &

31、#160;      <property name="target">  17.             <ref local="userServiceImp" />   18.       </propert

32、y>  19.         <!- 攔截器 ->  20.         <property name="interceptorNames">  21.            

33、0;<list>  22.                 <value>userInterceptor</value>  23.             </list>  24.   

34、60;     </property>  25.     </bean>  26.   27. </beans>  28. </span>    輸出:  user:shawn   printUser-!  printUser user:hello!  結(jié)論:調(diào)用方法的時(shí)

35、候 傳入的值被攔截修改了.攔截器中的事務(wù)管理(事務(wù)攔截機(jī)) 如果不采用攔截機(jī)的機(jī)制時(shí),在使用JDBC進(jìn)行數(shù)據(jù)庫(kù)訪(fǎng)問(wèn)時(shí),存在兩種情況: · 自動(dòng)提交        這是JDBC驅(qū)動(dòng)默認(rèn)的模式,每次數(shù)據(jù)庫(kù)操作(CRUD)成功完成后,都作為一個(gè)單獨(dú)的事務(wù)自動(dòng)提交,如果未成功完成,即拋出了 SQLException 的話(huà),僅最近的一個(gè)操作將回滾。 · 非自動(dòng)提交    這是想更好的控制事務(wù)時(shí)需要程序地方式進(jìn)行控制: o 在進(jìn)行該事務(wù)單元的任何操作之前 setAut

36、oCommit(false) o 在成功完成事務(wù)單元后 commit() o 在異常發(fā)生后 rollback()自動(dòng)提交模式是不被推薦的,因?yàn)槊總€(gè)操作都將產(chǎn)生一個(gè)事務(wù)點(diǎn),這對(duì)于大的應(yīng)用來(lái)說(shuō)性能將受到影響;再有,對(duì)于常見(jiàn)的業(yè)務(wù)邏輯,這種模式顯得無(wú)能為力。比如:轉(zhuǎn)帳,從A帳戶(hù)取出100元,將其存入B帳戶(hù);如果在這兩個(gè)操作之間發(fā)生了錯(cuò)誤,那么用戶(hù)A將損失了100元,而本來(lái)應(yīng)該給帳戶(hù)B的,卻因?yàn)槭〗o了銀行。所以,建議在所有的應(yīng)用中,如果使用 JDBC 都將不得不采用非自動(dòng)提交模式(你們要能發(fā)現(xiàn)了在我們的 JDBC 那個(gè)例子中,我們采用的就是自動(dòng)提交模式,我們是為了把精力放在JDBC上,而不是事務(wù)處理

37、上),即我們不得不在每個(gè)方法中:Java代碼  1. <span style="font-size: medium;">try       2.  / 在獲得連接后,立即通過(guò)調(diào)用setAutoCommit(false) 將事務(wù)處理置為非自動(dòng)提交模式  / Prepare Query to fetch the user Information

38、60;        3.      pst = conn.prepareStatement(findByName);                   4.        / 

39、.            mit();         5.    catch(Exception ex)          6.      conn.rollback();  &

40、#160;     7.       throw ex;         8.  finally      9.          try       10.

41、           / Close Result Set and Statement    11.           if (rset != null) rset.close();      &#

42、160;          12.          if (pst != null) pst.close();                     

43、60;    13.      catch (Exception ex)                  14.        ex.printStackTrace();     

44、0;            15.        throw new Exception("SQL Error while closing objects = " + ex.toString();        

45、;      16.     17.   18. </span>   這樣代碼在A(yíng)OP的倡導(dǎo)者看來(lái)是“骯臟”的代碼。他們認(rèn)為,所有的與事務(wù)有關(guān)的方法都應(yīng)當(dāng)可以集中配置(見(jiàn)聲明性事務(wù)控制),并自動(dòng)攔截,程序應(yīng)當(dāng)關(guān)心他們的主要任務(wù),即商業(yè)邏輯,而不應(yīng)和事務(wù)處理的代碼攪和在一起。我先看看 Spring 是怎么做到攔截的:1 Spring 內(nèi)置支持的事務(wù)處理攔截機(jī)這里因?yàn)橐玫絁petStore項(xiàng)目中的代碼,我們將 applicationCo

46、ntext.xml 全部?jī)?nèi)容列出:<?xml version="1.0" encoding="UTF-8"?><!- - Application context definition for JPetStore's business layer. - Contains bean references to the transaction manager and to the DAOs in - dataAccessContext-local/jta.xml (see web.xml's "contextConf

47、igLocation"). Jpetstore 的應(yīng)用上下文定義,包含事務(wù)管理和引用了在 dataAccessContext-local/jta.xml(具體使用了哪個(gè)要看 web.xml 中的 'contextConfigLocation' 的配置)中注冊(cè)的DAO-><beans xmlns="/schema/beans" xmlns:xsi="/2001/XMLSchema-instance" xmlns:aop="

48、;/schema/aop" xmlns:tx="/schema/tx" xsi:schemaLocation="/schema/beans /schema/beans/spring-beans-2.0.xsd /schema/aop http:/www.springfr

49、/schema/aop/spring-aop-2.0.xsd/schema/tx /schema/tx/spring-tx-2.0.xsd"> <!- = GENERAL DEFINITIONS = -> <!- Configurer that replaces $. placeholders with values from properties files 占位符的值將從列出的屬性文件中抽取出來(lái) -> <!-

50、 (in this case, mail and JDBC related properties) -> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>WEB-INF/perties</value>

51、<value>WEB-INF/perties</value> </list> </property> </bean> <!- MailSender used by EmailAdvice 指定用于發(fā)送郵件的 javamail 實(shí)現(xiàn)者,這里使用了 spring 自帶的實(shí)現(xiàn)。此 bean 將被 emailAdvice 使用 -> <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSen

52、derImpl"> <property name="host" value="$mail.host"/> </bean> <!- = BUSINESS OBJECT DEFINITIONS = -> <!- 不需要,因?yàn)楸?SpringMVC 的實(shí)現(xiàn)使用 Generic validator for Account objects, to be used for example by the Spring web tier -> <bean id="accountValidat

53、or" class="org.springframework.samples.jpetstore.domain.logic.AccountValidator"/> <!- 不需要,因?yàn)楸?SpringMVC 的實(shí)現(xiàn)使用 Generic validator for Order objects, to be used for example by the Spring web tier -> <bean id="orderValidator" class="org.springframework.samples.j

54、petstore.domain.logic.OrderValidator"/> <!- 主要的商業(yè)邏輯對(duì)象,即我們所說(shuō)的門(mén)面對(duì)象 注入了所有的DAO,這些DAO是引用了 dataAccessContext-xxx.xml 中定義的DAO 門(mén)面對(duì)象中的所有方法的事務(wù)控制將通過(guò)下面的 aop:config 來(lái)加以控制 - JPetStore primary business object (default implementation). - Transaction advice gets applied through the AOP configuration below

55、. -> <bean id="petStore" class="org.springframework.samples.jpetstore.domain.logic.PetStoreImpl"> <property name="accountDao" ref="accountDao"/> <property name="categoryDao" ref="categoryDao"/> <property name="p

56、roductDao" ref="productDao"/> <property name="itemDao" ref="itemDao"/> <property name="orderDao" ref="orderDao"/> </bean> <!- = ASPECT CONFIGURATION = -> <!- AOP配置,用來(lái)控制哪些方法將需要進(jìn)行事務(wù)處理,采用了AspectJ 的語(yǔ)法 -> <aop:conf

57、ig> <!- This definition creates auto-proxy infrastructure based on the given pointcut, expressed in AspectJ pointcut language. Here: applying the advice named "txAdvice" to all methods on classes named PetStoreImpl. -> <!- 指出在 PetStoreFacade 的所有方法都將采用 txAdvice(在緊接著的元素中定義了)事務(wù)方針,

58、注意,我們這里雖然指定的是接口 PetStoreFacace, 但其暗示著其所有的實(shí)現(xiàn)類(lèi)也將同樣具有這種性質(zhì),因?yàn)楸旧砭褪菍?shí)現(xiàn)類(lèi)的方法在執(zhí)行的,接口是沒(méi)有方法體的。 -> <aop:advisor pointcut="execution(* *.PetStoreFacade.*(.)" advice-ref="txAdvice"/> <!- This definition creates auto-proxy infrastructure based on the given pointcut, expressed in Aspe

59、ctJ pointcut language. Here: applying the advice named "emailAdvice" to insertOrder(Order) method of PetStoreImpl -> <!- 當(dāng)執(zhí)行 PetStoreFacade.insertOrder方法,該方法最后一個(gè)參數(shù)為Order類(lèi)型時(shí)(其實(shí)我們的例子中只有一個(gè) insertOrder 方法,但這告訴了我們,當(dāng)我們的接口或類(lèi)中有重載了的方法,并且各個(gè)重載的方法可能使用不同的攔截機(jī)機(jī)制時(shí),我們可以通過(guò)方法的參數(shù)加以指定),將執(zhí)行emailAdvice(在最后

60、定義的那個(gè)元素)-> <aop:advisor pointcut="execution(* *.PetStoreFacade.insertOrder(*.Order)" advice-ref="emailAdvice"/> </aop:config> <!- 事務(wù)方針聲明,用于控制采用什么樣的事務(wù)策略 Transaction advice definition, based on method name patterns. Defaults to PROPAGATION_REQUIRED for all methods

61、 whose name starts with "insert" or "update", and to PROPAGATION_REQUIRED with read-only hint for all other methods. -> <tx:advice id="txAdvice"> <tx:attributes> <tx:method name="insert*"/> <tx:method name="update*"/> <t

62、x:method name="*" read-only="true"/> </tx:attributes> </tx:advice> <!- 攔截機(jī),用于在適當(dāng)?shù)臅r(shí)機(jī)(通過(guò)AOP配置,如上面)在方法執(zhí)行成功后發(fā)送郵件 AOP advice used to send confirmation email after order has been submitted -> <!- -> <bean id="emailAdvice" class="org.springfr

63、amework.samples.jpetstore.domain.logic.SendOrderConfirmationEmailAdvice"> <property name="mailSender" ref="mailSender"/> </bean> <!- = 忽略 REMOTE EXPORTER DEFINITIONS = -> </beans>  這個(gè)配置比想象的要簡(jiǎn)單的多:Xml代碼  1. <span style="fo

64、nt-size: medium;"><aop:config>         2.  <!- This definition creates auto-proxy infrastructure based on the given pointcut, expressed in AspectJ pointcut

65、60;language.   3. Here: applying the advice named        "txAdvice" to all methods on classes named PetStoreImpl. 指出在 PetStoreFacade   4. 的所有方法都將采用 tx

66、Advice(在緊接著的元素中定義了)事務(wù)方針,注意,我們這里雖然指定的是接口 PetStoreFacace,          5.  但其暗示著其所有的實(shí)現(xiàn)類(lèi)也將同樣具有這種性質(zhì),因?yàn)楸旧砭褪菍?shí)現(xiàn)類(lèi)的方法在執(zhí)行的,接口是沒(méi)有方法體的。    ->     6.        <aop:advisor&#

67、160;pointcut="execution(* *.PetStoreFacade.*(.)" advice-ref="txAdvice"/>                 7.  <!- 其它攔截機(jī)->    8. </aop:config>  9. &

68、lt;/span>  1. 所有的攔截機(jī)配置都放在 <aop:config> 配置元素中.2. 下面還是需要理解一下幾個(gè)有關(guān)AOP的專(zhuān)用名詞,不過(guò),是挺抽象的,最好能會(huì)意出其的用意· pointcut 切入點(diǎn),比如:updateAccount 方法需要進(jìn)行事務(wù)管理,則這個(gè)切入點(diǎn)就是“執(zhí)行方法體”(execution)。Spring 所有支持的切入點(diǎn)類(lèi)型在都在 Spring reference: . Supported Pointcut Designators 中列出了。 · advice   

69、 要對(duì)這個(gè)切入點(diǎn)進(jìn)行什么操作,比如事務(wù)控制 · advisor   Spring 特有的概念,將上兩個(gè)概念合到一個(gè)概念中來(lái),即一個(gè) advisor 包含了一個(gè)切入點(diǎn)及對(duì)這個(gè)切入點(diǎn)所實(shí)施的操作。 因?yàn)?方法執(zhí)行切入點(diǎn) execution 為最常見(jiàn)的切入點(diǎn)類(lèi)型,我們著重介紹一下,execution 的完全形式為:execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)這是一個(gè)正則表達(dá)式,其中由 &#

70、39;?' 結(jié)尾的部分是可選的。翻譯過(guò)來(lái)就是:執(zhí)行(方法訪(fǎng)問(wèn)修飾符? 方法返回類(lèi)型 聲明類(lèi)型? 方法名(方法參數(shù)類(lèi)型) 拋出異常?)所有的這些都是用來(lái)定義執(zhí)行切入點(diǎn),即那些方法應(yīng)該被侯選為切入點(diǎn):· 方法訪(fǎng)問(wèn)修飾符   即 public, private 等等 · 方法返回類(lèi)型       即方法返回的類(lèi)型,如 void, String 等等 · 聲明類(lèi)型           &

71、#160;    1.5的語(yǔ)法,現(xiàn)在可以先忽略它 · 方法名                    方法的名字 · 方法參數(shù)類(lèi)型       方法的參數(shù)類(lèi)型 · 拋出異常           

72、0;    方法聲明的拋出的異常 例如,所有dao代碼被定義在包 com.xyz.dao及子包 com.xyz.dao.hibernate, 或者其它,如果還有的話(huà),子包中, 里面定義的是提供DAO功能的接口或類(lèi),那么表達(dá)式:execution(* com.xyz.dao.*.*(.)表示切入點(diǎn)為:執(zhí)行定義在包 com.xyz.dao 及其子包(因?yàn)?. 所致) 中的任何方法詳細(xì)情況可以參見(jiàn) Spring refernce: . Examples因此這個(gè)表達(dá)式為執(zhí)行定義在類(lèi) PetStoreFacade及其實(shí)現(xiàn)類(lèi)中的所有方法,采取的動(dòng)作定義在 txA

73、dvice 中. 關(guān)于該 advice 的定義,(見(jiàn)聲明性事務(wù)控制)一節(jié)<aop:advisor pointcut="execution(* *.PetStoreFacade.*(.)" advice-ref="txAdvice"/> 2 Spring 自定攔截機(jī)來(lái)為了進(jìn)行事務(wù)控制,我們只需簡(jiǎn)單地配置幾下,所有的工作都由 Spring 來(lái)做。這樣固然很好,但有時(shí)我們需要有我們特有的控制邏輯。因?yàn)镾pring 不可能包含所有人需要的所有攔截機(jī)。所以它提供了通過(guò)程序的方式加以定制的方式。我們的項(xiàng)目中就有這么一個(gè)攔截機(jī),在用戶(hù)確認(rèn)付款后,

74、將定單信息通過(guò) email 的方式發(fā)送給注冊(cè)用戶(hù)的郵箱中。<aop:config> . <!- 當(dāng)執(zhí)行 PetStoreFacade.insertOrder方法,該方法最后一個(gè)參數(shù)為Order類(lèi)型時(shí)(其實(shí)我們的例子中只有一個(gè) insertOrder 方法,但這告訴了我們,當(dāng)我們的接口或類(lèi)中有重載了的方法,并且各個(gè)重載的方法可能使用不同的攔截機(jī)機(jī)制時(shí),我們可以通過(guò)方法的參數(shù)加以指定),將執(zhí)行emailAdvice(在最后定義的那個(gè)元素)-> <aop:advisor pointcut="execution(* *.PetStoreFacade.insert

75、Order(*.Order)" advice-ref="emailAdvice"/> </aop:config>紅色的注釋已經(jīng)說(shuō)的很清楚這個(gè) Advisor 了,它的切入點(diǎn)(pointcut) 為 PetStoreFacade 的 void insertOrder(Order order) 方法,采取的動(dòng)作為引用的 emailAdvice, 下面我們就來(lái)看看 emailAdvice: <bean id="emailAdvice" class="org.springframework.samples.jpetst

76、ore.domain.logic.SendOrderConfirmationEmailAdvice"> <property name="mailSender" ref="mailSender"/> </bean>它給了這個(gè) advice 的實(shí)現(xiàn)類(lèi)為 logic 包中 SendOrderConfirmationEmailAdvice, 該Bean 引用了我們前面定義的郵件發(fā)送器(一個(gè) Spring 內(nèi)置的郵件發(fā)送器).下面看看這個(gè)實(shí)現(xiàn)類(lèi):public class SendOrderConfirmationEmailAdvice implements AfterReturningAdvice, InitializingBean / user jes on localhost private static final String DEFAULT_MAIL_FROM = "" private static final String DEFAULT_SUBJECT = "Thank you for your order!" private

溫馨提示

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

評(píng)論

0/150

提交評(píng)論