1. 程式人生 > >最全面的 Spring事務管理和AOP切面日誌的注入 —aop:pointcut expression解析

最全面的 Spring事務管理和AOP切面日誌的注入 —aop:pointcut expression解析

先來看看這個spring的配置檔案的配置:

  <!-- 事務管理器 -->
 <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="get*" propagation="REQUIRED" read-only="true" />
   <tx:method name="del*" propagation="REQUIRED" />
   <tx:method name="save*" propagation="REQUIRED" />
   <tx:method name="update*" propagation="REQUIRED" />
  </tx:attributes>
 </tx:advice>


 <!-- 配置事務攔截器攔截哪些類的哪些方法,一般設定成攔截Service -->
 <aop:config>
  <aop:pointcut expression="execution(* com.xy.service.*.*(..))"
   id="allDaoMethod" />
  <aop:advisor advice-ref="txAdvice" pointcut-ref="allDaoMethod" />
 </aop:config>


表示com.xy.service包下的所有方法為為事務管理。

execution(* com.aptech.jb.epet.dao.hibimpl.*.*(..)) 

這樣寫應該就可以了 這是com.aptech.jb.epet.dao.hibimpl 包下所有的類的所有方法。。

第一個*代表所有的返回值型別 

第二個*代表所有的類

第三個*代表類所有方法 最後一個..代表所有的引數。

下面給出一些常見切入點表示式的例子:

  • 任意公共方法的執行:

    execution(public * *(..))
    
  • 任何一個以“set”開始的方法的執行:

    execution(* set*(..))
    
  • AccountService 介面的任意方法的執行:

    execution(* com.xyz.service.AccountService.*(..))
    
  • 定義在service包裡的任意方法的執行:

    execution(* com.xyz.service.*.*(..))
    
  • 定義在service包或者子包裡的任意類的任意方法的執行:

    execution(* com.xyz.service..*.*(..))
    
AOP的理解 

         1、AOP的概述 
                   AOP是一種不同於OOP(面向物件程式設計)的程式設計模式,它不是OOP的替代,而是對OOP的一種有益補充。 
         2、spring AOP的原理 
         3、spring AOP的實現 
                   在spring2.5中,常用的AOP實現方式有兩種。第一種是基於xml配置檔案方式的實現,第二種是基於註解方式的實現。 
                   接下來,以具體的是理智講解這兩種方式的使用。 

Java程式碼   
package com.zxf.service;   
    
 /**  
 * 業務邏輯介面  
* @author z_xiaofei168  
 */   
 public interface AccountService {   
     public void save(String loginname, String password);   
 }   
    
它的實現類   
    
package com.zxf.service;   
 import com.zxf.dao.AccountDao;   
    
 /**  
 * AccountService的實現類  
* @author z_xiaofei168  
 */   
 public class AccountServiceImpl implements AccountService {   
     private  AccountDao accountDao;   
        
     public AccountServiceImpl() {}   
        
     /** 帶引數的構造方法 */   
     public AccountServiceImpl(AccountDao accountDao){   
         this.accountDao = accountDao;   
     }   
        
     public void save(String loginname, String password) {   
         accountDao.save(loginname, password);   
         throw new RuntimeException("故意丟擲一個異常。。。。");   
     }   
        
     /** set方法 */   
     public void setAccountDao(AccountDao accountDao) {   
         this.accountDao = accountDao;   
     }   
 }   
     
      對於業務系統來說,AccountServiceImpl類就是目標實現類,它的業務方法,如save()方法的前後或程式碼會出現異常的地方都是AOP的連線點。 

 下面是日誌服務類的程式碼: 


Java程式碼   
package com.zxf.aspect;   
    
 import org.aspectj.lang.JoinPoint;   
 import org.aspectj.lang.ProceedingJoinPoint;   
    
 /**  
 * 日誌切面類  
* @author z_xiaofei168  
 */   
 public class LogAspect {   
    
     //任何通知方法都可以將第一個引數定義為 org.aspectj.lang.JoinPoint型別    
     public void before(JoinPoint call) {   
         //獲取目標物件對應的類名   
         String className = call.getTarget().getClass().getName();   
         //獲取目標物件上正在執行的方法名   
         String methodName = call.getSignature().getName();   
            
         System.out.println("前置通知:" + className + "類的" + methodName + "方法開始了");   
     }   
        
     public void afterReturn() {   
         System.out.println("後置通知:方法正常結束了");   
     }   
        
     public void after(){   
         System.out.println("最終通知:不管方法有沒有正常執行完成,一定會返回的");   
     }   
        
     public void afterThrowing() {   
         System.out.println("異常丟擲後通知:方法執行時出異常了");   
     }   
        
     //用來做環繞通知的方法可以第一個引數定義為org.aspectj.lang.ProceedingJoinPoint型別   
     public Object doAround(ProceedingJoinPoint call) throws Throwable {   
         Object result = null;   
         this.before(call);//相當於前置通知   
         try {   
             result = call.proceed();   
             this.afterReturn(); //相當於後置通知   
         } catch (Throwable e) {   
    
             this.afterThrowing();  //相當於異常丟擲後通知   
             throw e;   
         }finally{   
             this.after();  //相當於最終通知   
         }   
            
         return result;   
     }   
 }   

      這個類屬於業務服務類,如果用AOP的術語來說,它就是一個切面類,它定義了許多通知。Before()、afterReturn()、after()和afterThrowing()這些方法都是通知。 

<1>.基於xml配置檔案的AOP實現 

         這種方式在實現AOP時,有4個步驟。 

Xml程式碼   
< ?xml version="1.0" encoding="UTF-8"?>   
< 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"   
         xsi:schemaLocation="   
             http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd   
             http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd>   
    
     <bean id="accountDaoImpl" class="com.zxf.dao.AccountDaoImpl"/>   
        
     <bean id="accountService" class="com.zxf.service.AccountServiceImpl">   
         <property name=" accountDaoImpl " ref=" accountDaoImpl "/>   
     </bean>   
    
     <!-- 日誌切面類 -->   
     <bean id="logAspectBean" class="com.zxf.aspect.LogAspect"/>   
        
     <!-- 第1步: AOP的配置 -->   
     <aop:config>   
         <!-- 第2步:配置一個切面 -->   
         <aop:aspect id="logAspect" ref="logAspectBean">   
             <!-- 第3步:定義切入點,指定切入點表示式 -->   
             <aop:pointcut id="allMethod"    
                 expression="execution(* com.zxf.service.*.*(..))"/>   
                    
             <!-- 第4步:應用前置通知 -->   
             <aop:before method="before" pointcut-ref="allMethod" />   
             <!-- 第4步:應用後置通知 -->   
             <aop:after-returning method="afterReturn" pointcut-ref="allMethod"/>   
             <!-- 第4步:應用最終通知 -->   
             <aop:after method="after" pointcut-ref="allMethod"/>   
             <!-- 第4步:應用丟擲異常後通知 -->   
             <aop:after-throwing method="afterThrowing" pointcut-ref="allMethod"/>   
                
             <!-- 第4步:應用環繞通知 -->   
             <!--   
             <aop:around method="doAround" pointcut-ref="allMethod" />  
              -->   
         </aop:aspect>   
     </aop:config>   
< /beans>   


     上述配置針對切入點應用了前置、後置、最終,以及丟擲異常後通知。這樣在測試執行AccountServiceImpl類的save()方法時,控制檯會有如下結果輸出。 

 前置通知:com.zxf.service.AccountServiceImpl類的save方法開始了。 
 針對MySQL的AccountDao實現中的save()方法。 
 後置通知:方法正常結束了。 
 最終通知:不管方法有沒有正常執行完成,一定會返回的。 
   <2>基於註解的AOP的實現 

    首先建立一個用來作為切面的類LogAnnotationAspect,同時把這個類配置在spring的配置檔案中。 
        在spring2.0以後引入了JDK5.0的註解Annotation的支援,提供了對AspectJ基於註解的切面的支援,從而 更進一步地簡化AOP的配置。具體的步驟有兩步。 

Spring的配置檔案是如下的配置: 


Xml程式碼   
< ?xml version="1.0" encoding="UTF-8"?>   
< 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"   
         xsi:schemaLocation="   
             http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd   
             http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd>   
    
     <bean id="accountDao" class="com.zxf.dao.AccountDaoImpl"/>   
     <bean id="accountService" class="com.zxf.service.AccountServiceImpl">   
         <property name="accountDao" ref="accountDao"/>   
     </bean>   
     <!-- 把切面類交由Spring容器來管理 -->   
     <bean id="logAspectBean" class="com.zxf.aspect.LogAnnotationAspect"/>   
     <!-- 啟用spring對AspectJ註解的支援 -->   
     <aop:aspectj-autoproxy/>   
< /beans>   

這是那個切面的類LogAnnotationAspect 
 Java程式碼   
package com.zxf.aspect;   
    
 import org.aspectj.lang.JoinPoint;   
 import org.aspectj.lang.ProceedingJoinPoint;   
 import org.aspectj.lang.annotation.After;   
 import org.aspectj.lang.annotation.AfterReturning;   
 import org.aspectj.lang.annotation.AfterThrowing;   
 import org.aspectj.lang.annotation.Aspect;   
 import org.aspectj.lang.annotation.Before;   
 import org.aspectj.lang.annotation.Pointcut;   
    
 /**  
 * 日誌切面類  
*/   
 @Aspect  //定義切面類   
public class LogAnnotationAspect {   
     @SuppressWarnings("unused")   
     //定義切入點   
     @Pointcut("execution(* com.zxf.service.*.*(..))")   
     private void allMethod(){}   
        
     //針對指定的切入點表示式選擇的切入點應用前置通知   
     @Before("execution(* com. zxf.service.*.*(..))")   
     public void before(JoinPoint call) {   
            
         String className = call.getTarget().getClass().getName();   
         String methodName = call.getSignature().getName();   
            
         System.out.println("【註解-前置通知】:" + className + "類的"    
                 + methodName + "方法開始了");   
     }   
     //訪問命名切入點來應用後置通知   
     @AfterReturning("allMethod()")   
     public void afterReturn() {   
         System.out.println("【註解-後置通知】:方法正常結束了");   
     }   
        
     //應用最終通知   
     @After("allMethod()")   
     public void after(){   
         System.out.println("【註解-最終通知】:不管方法有沒有正常執行完成,"    
                 + "一定會返回的");   
     }   
        
     //應用異常丟擲後通知   
     @AfterThrowing("allMethod()")   
     public void afterThrowing() {   
         System.out.println("【註解-異常丟擲後通知】:方法執行時出異常了");   
     }   
        
     //應用周圍通知   
     //@Around("allMethod()")   
     public Object doAround(ProceedingJoinPoint call) throws Throwable{   
         Object result = null;   
         this.before(call);//相當於前置通知   
         try {   
             result = call.proceed();   
             this.afterReturn(); //相當於後置通知   
         } catch (Throwable e) {   
             this.afterThrowing();  //相當於異常丟擲後通知   
             throw e;   
         }finally{   
             this.after();  //相當於最終通知   
         }   
            
         return result;   
     }   
 }

相關推薦

全面的 Spring事務管理AOP切面日誌注入aop:pointcut expression解析

先來看看這個spring的配置檔案的配置:   <!-- 事務管理器 -->  <bean id="transactionManager"   class="org.springframework.orm.hibernate3.HibernateTran

spring事務管理,xml配置aop事務註解配置aop事務

mov ref itcast template password nds eth poi ntc xml配置和註解配合共同代碼 AccountService.java public interface AccountService { //轉賬方法

spring事務管理aop

jdbc tran err att get ted cor cep pack 達內12 note unit 09 01 1.spring事務管理 2.spring提供了對事務管理支持 spring采用aop機制完成事務控制 可以實現在不修改原有組件代碼情況下實現事務控制功能

Spring---AOP註解開發&jdbc模板&Spring事務管理

use oca update -m spl pub tex com att 一、AOP註解開發   此處需要回憶一遍AOP的概念。簡單的來說,AOP就是利用動態代理技術,做到不觸動源代碼但卻擴展了功能。那麽就需要一個被擴展的對象和一個“新的功能”,例如說給某類的saveUs

Spring事務管理aop pointcut expression解析

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

淺談spring事務管理的2種方式:程式設計式事務管理宣告式事務管理;以及@Transactional(rollbackFor=Exception.class)註解用法

事務的概念,以及特性: 百度百科介紹: ->資料庫事務(Database Transaction) ,是指作為單個邏輯工作單元執行的一系列操作,要麼完全地執行,要麼完全地不執行。 事務處理可以確保除非事務性單元內的所有操作都成功完成,否則不會永久更新面向資料的資源。通過

spring事務管理,基於xml配置完成事務回滾;spring中資料庫表中欄位名pojo中屬性名不一致時候,實現RowMapper介面手動封裝

宣告使用JDK8,spring5.0.7, 測試說明: service 層 宣告介面進行轉賬,從A轉賬B ,然後對AB 進行更新操作,在事務中對find方法開啟 只讀許可權,無法進行更新操作,造成事務回滾進行測試事務; 主要測試方法:* void tra

spring事務管理原始碼分析(一)配置事務增強代理的生成流程

在本篇文章中,將會介紹如何在spring中進行事務管理,之後對其內部原理進行分析。主要涉及 @EnableTransactionManagement註解為我們做了什麼? 為什麼標註了@Transactional註解的方法就可以具有事務的特性,保持了資料的ACID特性?spring到底是如何具有這樣

spring事物配置,宣告式事務管理基於@Transactional註解的使用

spring支援程式設計式事務管理和宣告式事務管理兩種方式。         程式設計式事務管理使用TransactionTemplate或者直接使用底層的PlatformTransactionManager。對於程式設計式事務管理,spring推薦使用Transactio

25.Spring-事務管理-XML配置aop事務(重點)

="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.2.xsd http://www.springframework.org/schema/cache h

spring事務管理(詳解例項)

原文地址: 寫這篇部落格之前我首先讀了《Spring in action》,之後在網上看了一些關於Spring事務管理的文章,感覺都沒有講全,這裡就將書上的和網上關於事務的知識總結一下,參考的文章如下: 1 初步理解 理解事務之前,先講一個你日常生活中最常乾的事:取

Spring事務管理AOP方法

使用AOP完成Spring事務管理 <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <

【Spring4(三)】Spring事務管理JDBC模板的使用

Spring 的 AOP 的基於 AspectJ 註解開發 Spring 的基於AspectJ 的註解的 AOP 開發 建立專案,引入 jar 包 引入配置檔案 applicationContext.

SSH框架學習之Spring ---- 4、Spring事務管理jdbcTemplate

本節講的是spring對dao層的封裝,之前可能有更好的做法,但是要知道spring也提供了這種技術。 本節的主要內容是: 1、spring的jdbcTemplate操作(實現事務crud操作) 2、spring配置連線池 (1)配置c3p0連線池 (2)service和dao注

Spring事務管理資料庫事務相關知識

1 初步理解        理解事務之前,先講一個你日常生活中最常乾的事:取錢。         比如你去ATM機取1000塊錢,大體有兩個步驟:首先輸入密碼金額,銀行卡扣掉1000元錢;然後ATM出1000元錢。這兩個步驟必須是要麼都執行要麼都不執行。如果銀行卡扣除了1

由service層介面有什麼用?引申到基於JDK原生CGLIB動態代理實現spring事務管理的機制的思考

問題1:Services層為什麼要用(Services介面 類 + Services介面實現 類)分開,這樣做有什麼好處? 總結: 1.程式設計介面化, 2.Spring的事物管理預設用的是java動態代理。 問題2:Spring事物管理實現的機制

Spring事務管理aop:pointcut expression解析

先來看看這個spring的配置檔案的配置:   <!-- 事務管理器 -->  <bean id="transactionManager"   class="org.springframework.orm.hibernate3.HibernateTransactionManager"&

可能是漂亮的Spring事務管理詳解

事務概念回顧 什麼是事務? 事務是邏輯上的一組操作,要麼都執行,要麼都不執行. 事物的特性(ACID): 原子性: 事務是最小的執行單位,不允許分割。事務的原子性確保動作要麼全部完成,要麼完全不起作用; 一致性: 執行事

Spring程式設計式事務管理宣告式事務管理 案例

       轉賬案例使用了Spring事務管理,用兩種方式實現:程式設計式事務管理和宣告式事物管理。    其中,程式設計式事務管理是一種手動修改程式碼的方式,比較麻煩,在開發過程中很少使用;宣告式事務管理有三種方法實現,分別是TransactionProxyFacto

Spring事務管理--全面分析Spring的程式設計式事務管理及宣告式事務管理

Spring 的事務管理是 Spring 框架中一個比較重要的知識點,該知識點本身並不複雜,只是由於其比較靈活,導致初學者很難把握。本教程從基礎知識開始,詳細分析了 Spring 事務管理的使用方法,為讀者理清思路。 開始之前 關於本教程 本教程將深入講解 Spri