




版權(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 智能后視鏡行人檢測(cè)行業(yè)深度調(diào)研及發(fā)展戰(zhàn)略咨詢(xún)報(bào)告
- 哌嗪雌酮企業(yè)ESG實(shí)踐與創(chuàng)新戰(zhàn)略研究報(bào)告
- 2025年溫濕度儀表項(xiàng)目合作計(jì)劃書(shū)
- 2025年射頻消融治療儀項(xiàng)目合作計(jì)劃書(shū)
- 2025年幼兒園特色課程發(fā)展計(jì)劃
- 基于深度學(xué)習(xí)的線(xiàn)程組性能預(yù)測(cè)與優(yōu)化研究-洞察闡釋
- 2025年鉆采儀器項(xiàng)目建議書(shū)
- 一年級(jí)下冊(cè)數(shù)學(xué)復(fù)習(xí)與測(cè)評(píng)計(jì)劃
- 三年級(jí)語(yǔ)文詞匯積累和運(yùn)用計(jì)劃
- 醫(yī)療建筑文明施工管理計(jì)劃
- 甘肅酒泉事業(yè)單位考試筆試含答案2024
- 七下生物考試試卷及答案
- 財(cái)產(chǎn)險(xiǎn)試題庫(kù)及答案
- 湖南新高考教學(xué)教研聯(lián)盟暨長(zhǎng)郡二十校聯(lián)盟2025屆高三年級(jí)第二次聯(lián)考物理試題及答案
- 商品出庫(kù)管理規(guī)范
- 2025山東煙臺(tái)市蓬萊區(qū)城市建設(shè)投資集團(tuán)有限公司招聘22人筆試參考題庫(kù)附帶答案詳解
- 建筑勞務(wù)公司人事管理制度
- 應(yīng)聘人員登記表
- 2024年山東省公共衛(wèi)生臨床中心招聘筆試真題
- 2025年全國(guó)二模日語(yǔ)試題及答案
- 眼科學(xué)考試試題題庫(kù)
評(píng)論
0/150
提交評(píng)論