日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring AOP原理及拦截器

發布時間:2025/3/19 javascript 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring AOP原理及拦截器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原理

AOP(Aspect Oriented Programming),也就是面向方面編程的技術。AOP基于IoC基礎,是對OOP的有益補充。

  AOP將應用系統分為兩部分,核心業務邏輯(Core business concerns)及橫向的通用邏輯,也就是所謂的方面Crosscutting enterprise concerns,例如,所有大中型應用都要涉及到的持久化管理(Persistent)、事務管理(Transaction Management)、安全管理(Security)、日志管理(Logging)和調試管理(Debugging)等。

  AOP正在成為軟件開發的下一個光環。使用AOP,你可以將處理aspect的代碼注入主程序,通常主程序的主要目的并不在于處理這些aspect。AOP可以防止代碼混亂。

  Spring framework是很有前途的AOP技術。作為一種非侵略性的、輕型的AOP framework,你無需使用預編譯器或其他的元標簽,便可以在Java程序中使用它。這意味著開發團隊里只需一人要對付AOP framework,其他人還是像往常一樣編程。

  AOP概念

  讓我們從定義一些重要的AOP概念開始。

  — 方面(Aspect):一個關注點的模塊化,這個關注點實現可能另外橫切多個對象。事務管理是J2EE應用中一個很好的橫切關注點例子。方面用Spring的Advisor或攔截器實現。

  — 連接點(Joinpoint):程序執行過程中明確的點,如方法的調用或特定的異常被拋出。

  — 通知(Advice):在特定的連接點,AOP框架執行的動作。各種類型的通知包括“around”、“before”和“throws”通知。通知類型將在下面討論。許多AOP框架包括Spring都是以攔截器做通知模型,維護一個“圍繞”連接點的攔截器鏈。

  — 切入點(Pointcut):指定一個通知將被引發的一系列連接點的集合。AOP框架必須允許開發者指定切入點,例如,使用正則表達式。

  — 引入(Introduction):添加方法或字段到被通知的類。Spring允許引入新的接口到任何被通知的對象。例如,你可以使用一個引入使任何對象實現IsModified接口,來簡化緩存。

  — 目標對象(Target Object):包含連接點的對象,也被稱作被通知或被代理對象。

  — AOP代理(AOP Proxy):AOP框架創建的對象,包含通知。在Spring中,AOP代理可以是JDK動態代理或CGLIB代理。

  — 編織(Weaving):組裝方面來創建一個被通知對象。這可以在編譯時完成(例如使用AspectJ編譯器),也可以在運行時完成。Spring和其他純Java AOP框架一樣,在運行時完成織入。

  各種通知類型包括:

  —? Around通知:包圍一個連接點的通知,如方法調用。這是最強大的通知。Aroud通知在方法調用前后完成自定義的行為,它們負責選擇繼續執行連接點或通過返回它們自己的返回值或拋出異常來短路執行。

  —? Before通知:在一個連接點之前執行的通知,但這個通知不能阻止連接點前的執行(除非它拋出一個異常)。

  —? Throws通知:在方法拋出異常時執行的通知。Spring提供強制類型的Throws通知,因此你可以書寫代碼捕獲感興趣的異常(和它的子類),不需要從Throwable或Exception強制類型轉換。

  —? After returning通知:在連接點正常完成后執行的通知,例如,一個方法正常返回,沒有拋出異常。

  Around通知是最通用的通知類型。大部分基于攔截的AOP框架(如Nanning和Jboss 4)只提供Around通知。

  如同AspectJ,Spring提供所有類型的通知,我們推薦你使用最為合適的通知類型來實現需要的行為。例如,如果只是需要用一個方法的返回值來更新緩存,你最好實現一個after returning通知,而不是around通知,雖然around通知也能完成同樣的事情。使用最合適的通知類型使編程模型變得簡單,并能減少潛在錯誤。例如,你不需要調用在around通知中所需使用的MethodInvocation的proceed()方法,因此就調用失敗。

  切入點的概念是AOP的關鍵,它使AOP區別于其他使用攔截的技術。切入點使通知獨立于OO的層次選定目標。例如,提供聲明式事務管理的around通知可以被應用到跨越多個對象的一組方法上。 因此切入點構成了AOP的結構要素。

?攔截器(也稱攔截機)

??? 攔截機 (Interceptor), 是 AOP (Aspect-Oriented?Programming) 的另一種叫法。AOP本身是一門語言,只不過我們使用的是基于JAVA的集成到Spring 中的 SpringAOP。同樣,我們將通過我們的例子來理解陌生的概念。

?? 接口類

Java代碼??
  • ??package?com.test.TestSpring3;??
  • public?interface?UserService?//?被攔截的接口??
  • ...{??
  • ????public?void?printUser(String?user);??
  • }??
  • ?

    ?實現類

    Java代碼??
  • package?com.test.TestSpring3;??
  • ??
  • public?class?UserServiceImp?implements?UserService?//?實現UserService接口??
  • ...{??
  • ????public?void?printUser(String?user)?...{??
  • ????????System.out.println("printUser?user:"?+?user);//?顯示user??
  • ????}??
  • }??
  • ??
  • ?

    ?AOP攔截器

    Java代碼????
  • ??package?com.test.TestSpring3;
  • import?org.aopalliance.intercept.MethodInterceptor;??
  • import?org.aopalliance.intercept.MethodInvocation;??
  • ??
  • public?class?UserInterceptor?implements?MethodInterceptor??
  • //?AOP方法攔截器??
  • ...{??
  • ??
  • ????public?Object?invoke(MethodInvocation?arg0)?throws?Throwable?...{??
  • ??
  • ????????try?...{??
  • ??
  • ????????????if?(arg0.getMethod().getName().equals("printUser"))??
  • ????????????//?攔截方法是否是UserService接口的printUser方法??
  • ????????????...{??
  • ????????????????Object[]?args?=?arg0.getArguments();//?被攔截的參數??
  • ????????????????System.out.println("user:"?+?args[0]);??
  • ????????????????arg0.getArguments()[0]?=?"hello!";//?修改被攔截的參數??
  • ??
  • ????????????}??
  • ??
  • ????????????System.out.println(arg0.getMethod().getName()?+?"---!");??
  • ????????????return?arg0.proceed();//?運行UserService接口的printUser方法??
  • ??
  • ????????}?catch?(Exception?e)?...{??
  • ????????????throw?e;??
  • ????????}??
  • ????}??
  • }??
  • ?

    ?測試類

  • package?com.test.TestSpring3;??
  • ??
  • import?org.springframework.beans.factory.BeanFactory;??
  • ??
  • import?org.springframework.beans.factory.xml.XmlBeanFactory;??
  • import?org.springframework.context.ApplicationContext;??
  • import?org.springframework.context.support.ClassPathXmlApplicationContext;??
  • import?org.springframework.context.support.FileSystemXmlApplicationContext;??
  • import?org.springframework.core.io.ClassPathResource;??
  • import?org.springframework.core.io.Resource;??
  • import?org.springframework.web.context.support.WebApplicationContextUtils;??
  • ??
  • public?class?TestInterceptor?...{??
  • ??
  • ????public?static?void?main(String[]?args)?...{??
  • ????????ApplicationContext?ctx?=?new?FileSystemXmlApplicationContext(??
  • ????????????????"classpath:applicationContext.xml");??
  • //????????ApplicationContext?ctx?=?new?ClassPathXmlApplicationContext("applicationContext.xml");??????
  • ??????????
  • ????????UserService?us?=?(UserService)?ctx.getBean("userService");??
  • ????????us.printUser("shawn");??
  • ??
  • ????}??
  • }??
  • ?配置文件

    ?

    ??

  • <?xml?version="1.0"?encoding="UTF-8"?>??
  • <!DOCTYPE?beans?PUBLIC?"-//SPRING//DTD?BEAN//EN"?"http://www.springframework.org/dtd/spring-beans.dtd">??
  • <beans>??
  • ????<bean?id="userServiceImp"??
  • ????????class="com.test.TestSpring3.UserServiceImp"?/>??
  • ??
  • ????<bean?id="userInterceptor"?class="com.test.TestSpring3.UserInterceptor"?/>??
  • ??
  • ????<bean?id="userService"??
  • ????????class="org.springframework.aop.framework.ProxyFactoryBean">??
  • ??????<!--?代理接口?-->??
  • ????????<property?name="proxyInterfaces">??
  • ????????????<value>com.test.TestSpring3.UserService</value>??
  • ????????</property>??
  • ???????<!--?目標實現類?-->??
  • ????????<property?name="target">??
  • ????????????<ref?local="userServiceImp"?/>???
  • ??????</property>??
  • ????????<!--?攔截器?-->??
  • ????????<property?name="interceptorNames">??
  • ????????????<list>??
  • ????????????????<value>userInterceptor</value>??
  • ????????????</list>??
  • ????????</property>??
  • ????</bean>??
  • ??
  • </beans>??
  • ?

    ?輸出:
    ? user:shawn
    ?? printUser---!
    ? printUser?user:hello!?

    ?

    結論:調用方法的時候?傳入的值被攔截修改了.

    攔截器中的事務管理(事務攔截機)

    ?如果不采用攔截機的機制時,在使用JDBC進行數據庫訪問時,存在兩種情況:

    • 自動提交??????? 這是JDBC驅動默認的模式,每次數據庫操作(CRUD)成功完成后,都作為一個單獨的事務自動提交,如果未成功完成,即拋出了 SQLException 的話,僅最近的一個操作將回滾。
    • 非自動提交??? 這是想更好的控制事務時需要程序地方式進行控制:
      • 在進行該事務單元的任何操作之前?setAutoCommit(false)
      • 在成功完成事務單元后?commit()
      • 在異常發生后?rollback()

    ?

    自動提交模式是不被推薦的,因為每個操作都將產生一個事務點,這對于大的應用來說性能將受到影響;再有,對于常見的業務邏輯,這種模式顯得無能為力。比如:
    轉帳,從A帳戶取出100元,將其存入B帳戶;如果在這兩個操作之間發生了錯誤,那么用戶A將損失了100元,而本來應該給帳戶B的,卻因為失敗給了銀行。
    所以,建議在所有的應用中,如果使用 JDBC 都將不得不采用非自動提交模式(你們要能發現了在我們的 JDBC 那個例子中,我們采用的就是自動提交模式,我們是為了把精力放在JDBC上,而不是事務處理上),即我們不得不在每個方法中:

    Java代碼??
  • try?{??????
  • ?//?在獲得連接后,立即通過調用 setAutoCommit(false)?將事務處理置為非自動提交模式??//?Prepare?Query?to?fetch?the?user?Information?????????
  • ?????pst?=?conn.prepareStatement(findByName);???????????????????
  • ???????//?...????????????conn.commit();?????????
  • ?}??catch(Exception?ex)?{?????????
  • ?????conn.rollback();????????
  • ??????throw?ex;?????????
  • ?}finally?{?????
  • ?????????try?{??????
  • ???????????//?Close?Result?Set?and?Statement????
  • ??????????if?(rset?!=?null)?rset.close();?????????????????
  • ?????????if?(pst?!=?null)?pst.close();??????????????????????????
  • ????}?catch?(Exception?ex)?{?????????????????
  • ???????ex.printStackTrace();??????????????????
  • ???????throw?new?Exception("SQL?Error?while?closing?objects?=?"?+?ex.toString());??????????????
  • }????
  • }??
  • ??

    ?這樣代碼在AOP的倡導者看來是“骯臟”的代碼。他們認為,所有的與事務有關的方法都應當可以集中配置(見聲明性事務控制),并自動攔截,程序應當關心他們的主要任務,即商業邏輯,而不應和事務處理的代碼攪和在一起。

    我先看看 Spring 是怎么做到攔截的:

    Spring 內置支持的事務處理攔截機

    這里因為要用到JpetStore項目中的代碼,我們將 applicationContext.xml 全部內容列出:

    <?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 "contextConfigLocation").Jpetstore 的應用上下文定義,包含事務管理和引用了在 dataAccessContext-local/jta.xml(具體使用了哪個要看 web.xml 中的 'contextConfigLocation' 的配置)中注冊的DAO --> <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"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"><!-- ========================= GENERAL DEFINITIONS ========================= --><!-- Configurer that replaces ${...} placeholders with values from properties files 占位符的值將從列出的屬性文件中抽取出來--><!-- (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/mail.properties</value><value>WEB-INF/jdbc.properties</value></list></property></bean><!-- MailSender used by EmailAdvice 指定用于發送郵件的 javamail 實現者,這里使用了 spring 自帶的實現。此 bean 將被 emailAdvice 使用--><bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl"><property name="host" value="${mail.host}"/></bean><!-- ========================= BUSINESS OBJECT DEFINITIONS ======================== --><!-- 不需要,因為被 SpringMVC 的實現使用 Generic validator for Account objects, to be used for example by the Spring web tier --><bean id="accountValidator" class="org.springframework.samples.jpetstore.domain.logic.AccountValidator"/><!-- 不需要,因為被 SpringMVC 的實現使用 Generic validator for Order objects, to be used for example by the Spring web tier --><bean id="orderValidator" class="org.springframework.samples.jpetstore.domain.logic.OrderValidator"/><!--主要的商業邏輯對象,即我們所說的門面對象
    注入了所有的DAO,這些DAO是引用了 dataAccessContext-xxx.xml 中定義的DAO
    門面對象中的所有方法的事務控制將通過下面的 aop:config 來加以控制- JPetStore primary business object (default implementation).- Transaction advice gets applied through the AOP configuration below.--><bean id="petStore" class="org.springframework.samples.jpetstore.domain.logic.PetStoreImpl"><property name="accountDao" ref="accountDao"/><property name="categoryDao" ref="categoryDao"/><property name="productDao" ref="productDao"/><property name="itemDao" ref="itemDao"/><property name="orderDao" ref="orderDao"/></bean><!-- ========================= ASPECT CONFIGURATION ======================== --><!-- AOP配置,用來控制

    哪些

    方法將需要進行事務處理,采用了AspectJ 的語法 --><aop:config><!--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(在緊接著的元素中定義了)事務方針,注意,我們這里雖然指定的是接口 PetStoreFacace, 但其暗示著其所有的實現類也將
            同樣具有這種性質,因為本身就是實現類的方法在執行的,接口是沒有方法體的。 --><aop:advisor pointcut="execution(* *..PetStoreFacade.*(..))" advice-ref="txAdvice"/><!--This definition creates auto-proxy infrastructure based on the given pointcut,expressed in AspectJ pointcut language. Here: applying the advice named"emailAdvice" to insertOrder(Order) method of PetStoreImpl--><!-- 當執行 PetStoreFacade.insertOrder方法,該方法最后一個參數為Order類型時(其實我們的例子中只有一個 insertOrder 方法,但這告訴了我們,當我們的接口或類中有重載了的方法,
            并且各個重載的方法可能使用不同的攔截機機制時,我們可以通過方法的參數加以指定),將執行emailAdvice(在最后定義的那個元素)--><aop:advisor pointcut="execution(* *..PetStoreFacade.insertOrder(*..Order))" advice-ref="emailAdvice"/></aop:config><!--事務方針聲明,用于控制采用

    什么樣

    的事務策略Transaction advice definition, based on method name patterns.Defaults to PROPAGATION_REQUIRED for all methods whose name starts with"insert" or "update", and to PROPAGATION_REQUIRED with read-only hintfor all other methods.--><tx:advice id="txAdvice"><tx:attributes><tx:method name="insert*"/><tx:method name="update*"/><tx:method name="*" read-only="true"/></tx:attributes></tx:advice><!-- 攔截機,用于在適當的時機(通過AOP配置,如上面)在方法執行成功后發送郵件AOP advice used to send confirmation email after order has been submitted --><!-- --><bean id="emailAdvice" class="org.springframework.samples.jpetstore.domain.logic.SendOrderConfirmationEmailAdvice"><property name="mailSender" ref="mailSender"/></bean><!-- ========================= 忽略 REMOTE EXPORTER DEFINITIONS ======================== --></beans>

    ?

    ?

    這個配置比想象的要簡單的多:

    Xml代碼??
  • <aop:config>?????????
  • ?<!--?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(在緊接著的元素中定義了)事務方針,注意,我們這里雖然指定的是接口?PetStoreFacace,??????????
  • ?但其暗示著其所有的實現類也將同樣具有這種性質,因為本身就是實現類的方法在執行的,接口是沒有方法體的。????-->?????
  • ???????<aop:advisor?pointcut="execution(*?*..PetStoreFacade.*(..))"?advice-ref="txAdvice"/>?????????????????
  • ?<!--?其它攔截機-->????
  • </aop:config>??
  • ??

    1. 所有的攔截機配置都放在 <aop:config> 配置元素中.
    2. 下面還是需要理解一下幾個有關AOP的專用名詞,不過,是挺抽象的,最好能會意出其的用意

    • pointcut 切入點,比如:updateAccount 方法需要進行事務管理,則這個切入點就是“執行方法體”(execution)。Spring 所有支持的切入點類型在都在 Spring reference: 6.2.3.1. Supported Pointcut Designators 中列出了。
    • advice??? 要對這個切入點進行什么操作,比如事務控制
    • advisor?? Spring 特有的概念,將上兩個概念合到一個概念中來,即一個 advisor 包含了一個切入點及對這個切入點所實施的操作。

    因為 方法執行切入點 execution 為最常見的切入點類型,我們著重介紹一下,execution 的完全形式為:

    execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)

    這是一個正則表達式,其中由 '?' 結尾的部分是可選的。翻譯過來就是:

    執行(方法訪問修飾符? 方法返回類型 聲明類型? 方法名(方法參數類型) 拋出異常?)

    所有的這些都是用來定義執行切入點,即那些方法應該被侯選為切入點:

    • 方法訪問修飾符?? 即 public, private 等等
    • 方法返回類型?????? 即方法返回的類型,如 void, String 等等
    • 聲明類型?????????? ???? 1.5的語法,現在可以先忽略它
    • 方法名?????????? ???????? 方法的名字
    • 方法參數類型?????? 方法的參數類型
    • 拋出異常?????????? ???? 方法聲明的拋出的異常



    例如,所有dao代碼被定義在包 com.xyz.dao 及子包 com.xyz.dao.hibernate, 或者其它,如果還有的話,子包中, 里面定義的是提供DAO功能的接口或類,那么表達式:

    execution(* com.xyz.dao..*.*(..))

    表示切入點為:執行定義在包 com.xyz.dao 及其子包(因為?..?所致) 中的任何方法

    詳細情況可以參見 Spring refernce:?6.2.3.4. Examples


    因此這個表達式為執行定義在類 PetStoreFacade 及其實現類中的所有方法,采取的動作定義在 txAdvice 中. 關于該 advice 的定義,(見聲明性事務控制)一節

    <aop:advisor pointcut="execution(* *..PetStoreFacade.*(..))" advice-ref="txAdvice"/>

    ?

    Spring 自定攔截機

    來為了進行事務控制,我們只需簡單地配置幾下,所有的工作都由 Spring 來做。這樣固然很好,但有時我們需要有我們特有的控制邏輯。因為Spring 不可能包含所有人需要的所有攔截機。所以它提供了通過程序的方式加以定制的方式。我們的項目中就有這么一個攔截機,在用戶確認付款后,將定單信息通過 email 的方式發送給注冊用戶的郵箱中。

    <aop:config>...<!-- 當執行 PetStoreFacade.insertOrder方法,該方法最后一個參數為Order類型時(其實我們的例子中只有一個 insertOrder 方法,但這告訴了我們,當我們的接口或類中有重載了的方法,
            并且各個重載的方法可能使用不同的攔截機機制時,我們可以通過方法的參數加以指定),將執行emailAdvice(在最后定義的那個元素)--><aop:advisor pointcut="execution(* *..PetStoreFacade.insertOrder(*..Order))" advice-ref="emailAdvice"/></aop:config>

    紅色的注釋已經說的很清楚這個 Advisor 了,它的切入點(pointcut) 為 PetStoreFacade 的 void insertOrder(Order order) 方法,采取的動作為引用的 emailAdvice, 下面我們就來看看 emailAdvice:

    <bean id="emailAdvice" class="org.springframework.samples.jpetstore.domain.logic.SendOrderConfirmationEmailAdvice"><property name="mailSender" ref="mailSender"/></bean>

    它給了這個 advice 的實現類為 logic 包中 SendOrderConfirmationEmailAdvice, 該Bean 引用了我們前面定義的郵件發送器(一個 Spring 內置的郵件發送器).

    下面看看這個實現類:

    public class SendOrderConfirmationEmailAdvice implements AfterReturningAdvice, InitializingBean {// user jes on localhostprivate static final String DEFAULT_MAIL_FROM = "test@pprun.org";private static final String DEFAULT_SUBJECT = "Thank you for your order!";private final Log logger = LogFactory.getLog(getClass());private MailSender mailSender;private String mailFrom = DEFAULT_MAIL_FROM;private String subject = DEFAULT_SUBJECT;public void setMailSender(MailSender mailSender) {
    this.mailSender = mailSender;
    }public void setMailFrom(String mailFrom) {this.mailFrom = mailFrom;}public void setSubject(String subject) {this.subject = subject;}public void throws Exception {if (this.mailSender == null) {throw new IllegalStateException("mailSender is required");}}/**
    *
    * @param returnValue 被攔截的方法的返回值
    * @param m 被攔截的方法的所有信息(Method類封裝了這些信息)
    * @param args 被攔截的方法的所有參數組成的數組
    * @param target 目標對象,對于方法執行來說,即是方法所在的類的實例(與 this 同,批當前對象)
    * @throws java.lang.Throwable
    */public void afterReturning(Object returnValue, Method m, Object[] args, Object target) throws Throwable {// 我們被攔截的方法為 void insertOrder(Order order),方法只有一個參數,所以可知數據的第1個元素即是被傳進的 order 對象// 得到了order 對象,就可以將 order 對應的帳戶名及帳單號發送到郵件中,以便確認無誤。Order order = (Order) args[0];Account account = ((PetStoreFacade) target).getAccount(order.getUser().getUsername());// don't do anything if email address is not setif (account.getEmail() == null || account.getEmail().length() == 0) {return;}StringBuffer text = new StringBuffer();text.append("Dear ").append(account.getFirstname()).append(' ').append(account.getLastname());text.append(", thank your for your order from JPetStore. " +"Please note that your order number is ");text.append(order.getId());SimpleMailMessage mailMessage = new SimpleMailMessage();mailMessage.setTo(account.getEmail());mailMessage.setFrom(this.mailFrom);mailMessage.setSubject(this.subject);mailMessage.setText(text.toString());try {this.mailSender.send(mailMessage);} catch (MailException ex) {// just log it and go onlogger.warn("An exception occured when trying to send email", ex);}}}

    ?

    1.?紅色的內容即為反向注入的?mailSender?屬性

    2.?藍色的內容為 Spring Bean 的一個通用的接口?InitializingBean?,實現類需要實現該接口定義的方法?afterPropertiesSet()?,該方法中一般是在Bean 被初始化后并設置了所有的 setter 注入后調用的。所以這里是保證郵件發送器配置正確。因為如果沒有配置正確,下面的工作是無法進行的,所以與其等那時拋出異常,還不如早早地在部署時就告知(通過拋出 IllegalStateException 來提示)

    3.?綠色的內容為這個 Advise 的核心,即在切入點被切入后將采用的動作。因為 Advise 也同樣有多種類型,比如我們這里的“方法正常返回”,“方法執行前”,“方法執行后”,“環繞在方法執行前后”,“方法拋出異常時”等等(詳情參見 Spring Reference:?6.2.4. Declaring advice)。但是我們的邏輯為在用戶確認定單并且執行成功(所謂的成功是指將這一定單插入到了表 Order 中了)后,將發送一確認信。所以”方法正常返回“完全符合我們的要求。
    接口AfterReturningAdvice?即是 Spring中表示”方法正常返回“ 這一語義的 Advice, 所以我們實現這個接口及其必須的方法?afterReturning.
    方法代碼的工作其實并不重要,只要我們理解這些“魔法”一樣的技術后,實現代碼是很簡單的。值得提及的是這個方法的參數,這些參數是封裝了切入點的所有信息,請見上面的注釋。在我們的實現中只使用了被攔截方法的參數,在復雜的 Advice 實現中可能會用到切入點所有信息。

    轉載于:https://www.cnblogs.com/xtdxs/p/6527451.html

    總結

    以上是生活随笔為你收集整理的Spring AOP原理及拦截器的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 99re视频这里只有精品 | www日| 新版天堂资源中文8在线 | 夜色成人 | 国产色爽 | 久久综合激情网 | 日本一区二区欧美 | 国产av人人夜夜澡人人爽麻豆 | 人人射人人干 | 久久免费少妇高潮久久精品99 | 污视频网站免费看 | 亚洲精品69 | 69xxxx日本| 视频在线国产 | 91黄色在线视频 | 激情视频激情小说 | 欧美日韩成人免费观看 | 春草| 草草国产 | 男人网站在线观看 | 男女超碰 | 国产色播av在线 | 国产精品久久欧美久久一区 | 精品人妻在线播放 | 男人的天堂在线视频 | 成人av高清 | 麻豆chinese新婚xxx | 一区二区不卡视频 | 麻豆视频免费看 | 丹丹的呻吟声1一7 | 日本特级黄色 | 欧美性网址 | 国产精品久久久久久中文字 | 美女又黄又免费 | 黄色免费在线网站 | yy1111111| 日本黄网站在线观看 | 欧美bdsm调教视频 | aaaa黄色片 | 日本成人免费观看 | 久久午夜免费视频 | 亚洲色婷婷久久精品av蜜桃 | 91高清视频免费观看 | 久久国产乱子 | 在线午夜 | 国产丰满农村老妇女乱 | 欧美做爰全过程免费看 | 欧美日韩在线视频一区二区 | 刘亦菲久久免费一区二区 | 国产精品久久久久毛片 | 91精品国产综合久久久蜜臀 | 国产拍拍拍拍拍拍拍拍拍拍拍拍拍 | youjizzcom日本 | 亚洲青涩在线 | 先锋资源在线视频 | 国产三级三级看三级 | 亚洲精品喷潮一区二区三区 | 国产成人av影院 | 天天操天天干天天摸 | 玉势 (1v1 高h) | 日韩综合一区二区三区 | 激情五月婷婷综合 | 国产女人高潮视频 | 强开乳罩摸双乳吃奶羞羞www | 99成人国产精品视频 | 涩涩资源站| 亚洲a视频在线 | 日韩婷婷| 久久不卡 | 特黄视频免费看 | 欧美一区二区三区四区五区 | 福利在线免费 | 欧美日韩色图 | 欧美老肥婆性猛交视频 | 97久久国产亚洲精品超碰热 | 日本在线播放一区 | 双性尿奴穿贞c带憋尿 | 欧美图片一区 | 日本特黄色片 | 小早川怜子久久精品中文字幕 | 亚洲日本久久 | 男女搞鸡网站 | 国产精品v欧美精品v日韩 | 国产精品熟女一区二区不卡 | 偷拍亚洲另类 | 丁香花五月 | 亚洲综合精品国产一区二区三区 | 中文字幕在线观看一区 | www.超碰在线 | 新香蕉视频 | 国产一区二区在线免费观看视频 | 91av色| 激情五月视频 | 国产精品videos| 午夜爽爽爽视频 | 少妇特黄a一区二区三区 | 美女裸体网站久久久 | 国外精品视频 | 色哟哟免费在线观看 |