Spring Aop實例之AspectJ註解配置

http://blog.csdn.net/xiaoxian8023/article/details/17285809html

上篇博文《Spring Aop實例之xml配置》中,講解了xml配置方式,今天來講說AspectJ註解方式去配置spring aop。java

 

       依舊採用的jdk代理,接口和實現類代碼請參考上篇博文。主要是將Aspect類分享一下:web

 

[java]  view plain copy 在CODE上查看代碼片 派生到個人代碼片
 
  1. package com.tgb.aop;  
  2.   
  3. import org.aspectj.lang.JoinPoint;  
  4. import org.aspectj.lang.ProceedingJoinPoint;  
  5. import org.aspectj.lang.annotation.After;  
  6. import org.aspectj.lang.annotation.AfterReturning;  
  7. import org.aspectj.lang.annotation.AfterThrowing;  
  8. import org.aspectj.lang.annotation.Around;  
  9. import org.aspectj.lang.annotation.Aspect;  
  10. import org.aspectj.lang.annotation.Before;  
  11. import org.aspectj.lang.annotation.DeclareParents;  
  12. import org.aspectj.lang.annotation.Pointcut;  
  13.   
  14. /** 
  15.  * 測試after,before,around,throwing,returning Advice. 
  16.  * @author Admin 
  17.  * 
  18.  */  
  19. @Aspect  
  20. public class AspceJAdvice {  
  21.   
  22.     /** 
  23.      * Pointcut 
  24.      * 定義Pointcut,Pointcut的名稱爲aspectjMethod(),此方法沒有返回值和參數 
  25.      * 該方法就是一個標識,不進行調用 
  26.      */  
  27.     @Pointcut("execution(* find*(..))")  
  28.     private void aspectjMethod(){};  
  29.       
  30.     /**  
  31.      * Before 
  32.      * 在覈心業務執行前執行,不能阻止核心業務的調用。 
  33.      * @param joinPoint  
  34.      */    
  35.     @Before("aspectjMethod()")    
  36.     public void beforeAdvice(JoinPoint joinPoint) {    
  37.         System.out.println("-----beforeAdvice().invoke-----");  
  38.         System.out.println(" 此處意在執行核心業務邏輯前,作一些安全性的判斷等等");  
  39.         System.out.println(" 可經過joinPoint來獲取所須要的內容");  
  40.         System.out.println("-----End of beforeAdvice()------");  
  41.     }  
  42.       
  43.     /**  
  44.      * After  
  45.      * 核心業務邏輯退出後(包括正常執行結束和異常退出),執行此Advice 
  46.      * @param joinPoint 
  47.      */  
  48.     @After(value = "aspectjMethod()")    
  49.     public void afterAdvice(JoinPoint joinPoint) {    
  50.         System.out.println("-----afterAdvice().invoke-----");  
  51.         System.out.println(" 此處意在執行核心業務邏輯以後,作一些日誌記錄操做等等");  
  52.         System.out.println(" 可經過joinPoint來獲取所須要的內容");  
  53.         System.out.println("-----End of afterAdvice()------");  
  54.     }    
  55.   
  56.     /**  
  57.      * Around  
  58.      * 手動控制調用核心業務邏輯,以及調用前和調用後的處理, 
  59.      *  
  60.      * 注意:當核心業務拋異常後,當即退出,轉向AfterAdvice 
  61.      * 執行完AfterAdvice,再轉到ThrowingAdvice 
  62.      * @param pjp 
  63.      * @return 
  64.      * @throws Throwable 
  65.      */   
  66.     @Around(value = "aspectjMethod()")    
  67.     public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {    
  68.         System.out.println("-----aroundAdvice().invoke-----");  
  69.         System.out.println(" 此處能夠作相似於Before Advice的事情");  
  70.           
  71.         //調用核心邏輯  
  72.         Object retVal = pjp.proceed();  
  73.         System.out.println(" 此處能夠作相似於After Advice的事情");  
  74.         System.out.println("-----End of aroundAdvice()------");  
  75.         return retVal;  
  76.     }    
  77.       
  78.     /**  
  79.      * AfterReturning  
  80.      * 核心業務邏輯調用正常退出後,不論是否有返回值,正常退出後,均執行此Advice 
  81.      * @param joinPoint 
  82.      */   
  83.     @AfterReturning(value = "aspectjMethod()", returning = "retVal")    
  84.     public void afterReturningAdvice(JoinPoint joinPoint, String retVal) {    
  85.         System.out.println("-----afterReturningAdvice().invoke-----");  
  86.         System.out.println("Return Value: " + retVal);   
  87.         System.out.println(" 此處能夠對返回值作進一步處理");  
  88.         System.out.println(" 可經過joinPoint來獲取所須要的內容");  
  89.         System.out.println("-----End of afterReturningAdvice()------");  
  90.     }  
  91.       
  92.     /** 
  93.      * 核心業務邏輯調用異常退出後,執行此Advice,處理錯誤信息 
  94.      *  
  95.      * 注意:執行順序在Around Advice以後 
  96.      * @param joinPoint 
  97.      * @param ex 
  98.      */  
  99.     @AfterThrowing(value = "aspectjMethod()", throwing = "ex")    
  100.     public void afterThrowingAdvice(JoinPoint joinPoint, Exception ex) {    
  101.         System.out.println("-----afterThrowingAdvice().invoke-----");  
  102.         System.out.println(" 錯誤信息:"+ex.getMessage());  
  103.         System.out.println(" 此處意在執行核心業務邏輯出錯時,捕獲異常,並可作一些日誌記錄操做等等");  
  104.         System.out.println(" 可經過joinPoint來獲取所須要的內容");  
  105.         System.out.println("-----End of afterThrowingAdvice()------");    
  106.     }    
  107. }  



 

       application-config.xml中,只須要配置業務邏輯bean和Aspect bean,並啓用Aspect註解便可:spring

 
    1. <?xml version="1.0" encoding="UTF-8"?>  
    2.   
    3. <beans xmlns="http://www.springframework.org/schema/beans"  
    4.          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    5.          xmlns:aop="http://www.springframework.org/schema/aop"  
    6.          xmlns:tx="http://www.springframework.org/schema/tx"  
    7.          xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd  
    8.            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd  
    9.            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">  
    10.              
    11.     <!-- 啓用AspectJ對Annotation的支持 -->         
    12.     <aop:aspectj-autoproxy/>             
    13.       
    14.     <bean id="userManager" class="com.tgb.aop.UserManagerImpl"/>  
    15.     <bean id="aspcejHandler" class="com.tgb.aop.AspceJAdvice"/>  
    16.       
    17. </beans>  

 

經過測試的發現AroundAdvice、BeforeAdvice、AfterAdvice、ReturningAdvice的執行順序是根據註解的順序而定的。可是有時候修改了順序,結果卻沒有變化,多是緩存的緣故。前幾天我也遇到了這樣的問題,不過今天再測試了一下,發現執行順序又跟註解的順序一致了。緩存

 

       xml 和 Annotation 註解均可以做爲配置項,對Spring AoP進行配置管理,那麼它們各自都有什麼優缺點呢?

  首先說說 xml 。目前 web 應用中幾乎都使用 xml 做爲配置項,例如咱們經常使用的框架 Struts、Spring、Hibernate 等等都採用 xml 做爲配置。xml 之因此這麼流行,是由於它的不少優勢是其它技術的配置所沒法替代的:安全

    • xml 做爲可擴展標記語言最大的優點在於開發者可以爲軟件量身定製適用的標記,使代碼更加通俗易懂。
    • 利用 xml 配置能使軟件更具擴展性。例如 Spring 將 class 間的依賴配置在 xml 中,最大限度地提高應用的可擴展性。
    • 具備成熟的驗證機制確保程序正確性。利用 Schema 或 DTD 能夠對 xml 的正確性進行驗證,避免了非法的配置致使應用程序出錯。
    • 修改配置而無需變更現有程序。

  雖然有如此多的好處,但畢竟沒有什麼萬能的東西,xml 也有自身的缺點。app

    • 須要解析工具或類庫的支持。
    • 解析 xml 勢必會影響應用程序性能,佔用系統資源。
    • 配置文件過多致使管理變得困難。
    • 編譯期沒法對其配置項的正確性進行驗證,或要查錯只能在運行期。
    • IDE 沒法驗證配置項的正確性無能爲力。
    • 查錯變得困難。每每配置的一個手誤致使莫名其妙的錯誤。
    • 開發人員不得不一樣時維護代碼和配置文件,開發效率變得低下。
    • 配置項與代碼間存在潛規則。改變了任何一方都有可能影響另一方。

  讓咱們來看看 Annotation 的優勢。框架

    • 保存在 class 文件中,下降維護成本。
    • 無需工具支持,無需解析。
    • 編譯期便可驗證正確性,查錯變得容易。
    • 提高開發效率。

  一樣 Annotation 也不是萬能的,它也有不少缺點。工具

    • 若要對配置項進行修改,不得不修改 Java 文件,從新編譯打包應用。
    • 配置項編碼在 Java 文件中,可擴展性差。

  總結:沒有一個事物是萬能的,一樣 xml 和 Java Annotation 都有各自的優缺點。經過以上對比,細心的讀者可能已經發現它們的優缺點偏偏是互補的。xml 的強項是 Annotation 所不具有的,而 Annotation 的優點也是 xml 所欠缺的。這也正是時下流行的 xml + Annotation 配置的緣由所在。平衡纔是王道呀!性能

相關文章
相關標籤/搜索