1. 程式人生 > >AOP的一些東西(事務的傳播特性,前置,後置,環繞,異常 等各種通知)

AOP的一些東西(事務的傳播特性,前置,後置,環繞,異常 等各種通知)

1、事務的配置

基本的六種事務傳播:

1. PROPAGATION_REQUIRED: 如果存在一個事務,則支援當前事務。如果沒有事務則開啟(常用的配置)
2. PROPAGATION_SUPPORTS: 如果存在一個事務,支援當前事務。如果沒有事務,則非事務的執行
3. PROPAGATION_MANDATORY: 如果已經存在一個事務,支援當前事務。如果沒有一個活動的事務,則丟擲異常。
4. PROPAGATION_REQUIRES_NEW: 總是開啟一個新的事務。如果一個事務已經存在,則將這個存在的事務掛起。
5. PROPAGATION_NOT_SUPPORTED: 總是非事務地執行,並掛起任何存在的事務。
6. PROPAGATION_NEVER: 總是非事務地執行,如果存在一個活動事務,則丟擲異常

Spring配置宣告式事務:

* 配置SessionFactory
* 配置事務管理器
* 事務的傳播特性
* 那些類那些方法使用事務

2、編寫業務邏輯方法
* 繼承HibernateDaoSupport類,使用HibernateTemplate來持久化,HibernateTemplate是
   Hibernate Session的輕量級封裝
* 預設情況下執行期異常才會回滾(包括繼承了RuntimeException子類),普通異常是不會滾的
* 編寫業務邏輯方法時,最好將異常一直向上丟擲,在表示層(struts)處理
* 關於事務邊界的設定,通常設定到業務層,不要新增到Dao上

<!-- 配置SessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="configLocation">
     <value>classpath:hibernate.cfg.xml</value>
    </property>
</bean>

<!-- 配置事務管理器 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>

<!-- 事務的傳播特性 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
     <tx:method name="add*" propagation="REQUIRED"/>
     <tx:method name="del*" propagation="REQUIRED"/>
     <tx:method name="modify*" propagation="REQUIRED"/>
     <tx:method name="*" propagation="REQUIRED" read-only="true"/>
    </tx:attributes>
</tx:advice>

<!-- 哪些類哪些方法使用事務 -->
<aop:config>
    <aop:pointcut expression="execution(* com.biped.service.*.*(..))" id="transactionPC"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="transactionPC"/>
</aop:config>

<!-- 普通IOC注入 -->
<bean id="userManager" class="com.biped.service.UserManagerImpl">
    <property name="logManager" ref="logManager"/>
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>
<bean id="logManager" class="com.biped.service.LogManagerImpl">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>

2、宣告一個切面

              在基於AOP名稱空間的Spring AOP中,要宣告一個切面,需要使用<aop:config/>的子標籤<aop:aspect>。<aop:aspect>標籤有一個ref屬性必須被賦值,它用於指定和該切面關聯的受管Bean(backing bean,以後我們都將使用Backing Bean來稱呼這樣的Bean)。正如下例所示,該Bean對應的java類是一個普通的java類,在該類中定義了切面的通知方法。此外,<aop:aspect>標籤還有兩個可選的order屬性和id屬性,order屬性用於指定該切面的載入順序,id屬性用於標識該切面。範例如下:

簡單的說就是來宣告處理日誌,事務等方法的來源

Xml程式碼 複製程式碼

3、宣告一個切入點
      要宣告一個切入點,可以使用<aop:aspect>的子標籤<aop:pointcut>,在Spring2.5中它有兩個屬性id和expression,分別用於標示該切入點和設定該切入點表示式。例如:

Xml程式碼 複製程式碼


<aop:pointcut>標籤的expression屬性使用前面介紹的切入點表示式語言,也就是說支援AspectJ切入點表示式。但是由於xml對"&&"、"||"、"!"等邏輯運算子不友好,@AspectJ切入點表示式語言中使用的這些邏輯運算子在xml配置中需要分別用"and"、"or"和"not"來代替。
有時候,我們也需要在xml中使用@Pointcut註解宣告的切入點,那麼該如何呢?大家可能記得,我們可以在切入點表示式中可以引用另一個切入點。對了,就在這裡,我們使用該特性可以完成這個任務,如下:

Xml程式碼 複製程式碼

注意:這裡我們必須使用全路徑來標示引用的切入點。

4、 宣告一個通知
      和@AspectJ一樣,基於AOP名稱空間的配置也可以定義五種通知型別,並且使用方式和特性類似。與@AspectJ不同的是,配置資訊從Annotation中轉移到了xml配置檔案。
    1)、前置通知
    宣告一個前置通知可以使用<aop:aspect>的子標籤<aop:before/>。該標籤的屬性說明如下表:

<aop:before/>標籤屬性說明

屬性 <o:p> </o:p>

說明 <o:p> </o:p>

pointcut<o:p></o:p>

指定該通知的內建切入點 <o:p> </o:p>

pointcut-ref<o:p></o:p>

通過 id 引用已定義的切入點 <o:p> </o:p>

method<o:p></o:p>

指定通知對應的方法,該方法必須已在切面的 backing bean 中被宣告 <o:p> </o:p>

arg-names<o:p></o:p>

通過方法的引數名字來匹配切入點引數 <o:p> </o:p>

      對於一個通知來說,切入點和對應的通知方法是必須的。也就是說,在這些屬性中,method屬性是必須的,我們必須要給通知指定一個對應的方法;pointcut屬性和pointcut-ref必須有一個被指定,以此確定該通知的切入點。範例如下:

Xml程式碼 複製程式碼

     2)、 後置通知
     宣告一個後置通知使用<aop:after/>標籤,它的屬性等和<aop:before/>標籤類似,下面是範例:

Xml程式碼 複製程式碼

     3)、 返回後通知
      <aop:after-returning/>標籤可以宣告一個返回後通知,該標籤的屬性和<aop:before/>相比它多了一個returning屬性。該屬性的意義類似於@AfterReturning註解的returning屬性,用於將連結點的返回值傳給通知方法。用法如下:

Xml程式碼 複製程式碼

       4)、 異常通知
        宣告一個異常通知使用<aop:after-throwing />標籤,它有一個類似於throwing屬性又來指定該通知匹配的異常型別。用法如下:

Xml程式碼 複製程式碼

      5)、 環繞通知
      環繞通知是所有通知中功能最強大的通知,用<aop:around/>標籤來宣告。用法如下:

Xml程式碼 複製程式碼
  1. <aop:aspect ref="MyAspect" order="0" id="Test">  
  2.     <aop:pointcut id="testPointcut"  
  3.         expression="execution(* aop.test.TestBean.*(..))" />  
  4.         <aop:around pointcut-ref="testPointcut" method="aroundAdvice"/>  
  5. </aop:aspect>