posts - 297,  comments - 1618,  trackbacks - 0
                  Spring支持四種攔截類型:目標(biāo)方法調(diào)用前(before),目標(biāo)方法調(diào)用后(after),目標(biāo)方法調(diào)用前后(around),以及目標(biāo)方法拋出異常(throw)。
                   最近用到spring的AOP來實現(xiàn)異常攔截,用到了spring的ThrowsAdvice。ThrowsAdvice是一個標(biāo)示接口,我們可以在類中定義一個或多個,來捕獲定義異常通知的bean拋出的異常,并在拋出異常前執(zhí)行相應(yīng)的方法。
                  我想大家可能都在項目中有過這樣的需求,想在某種異常拋出時進(jìn)行一些記錄操作,例如記錄錯誤日志到數(shù)據(jù)庫或日志文件中,但把這些代碼分布到項目各處不但難于管理,并且代碼量巨大,用Spring的AOP來實現(xiàn)攔截不失為一個比較好的方法。
                  下面,讓我們來感受一下它的魅力吧。
           1. 操作類TestBean
          /**
           * Copyright 2007 GuangZhou Cotel Co. Ltd.
           * All right reserved.    
           * 測試異常攔截的bean     
           * 
          @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
           * 
          @version 1.0 
           * Creation date: 2007-7-24 - 下午08:00:37
           
          */

          public class TestBean {
              
          public void method1() throws Exception {
                  
          throw new Exception("Exception happened!");
              }


              
          /**
               * 將字符串轉(zhuǎn)換為整數(shù).
               * 
          @param number 需轉(zhuǎn)換的字符串
               * 
          @return 轉(zhuǎn)換成的字符串
               * 
          @throws NumberFormatException
               * 
          @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
               * Creation date: 2007-7-24 - 下午08:05:41
               
          */

              
          public int changeToNumber(String number) throws NumberFormatException {
                  
          //當(dāng)number為空或非數(shù)字時,將拋出NumberFormatException
                  int num = Integer.parseInt(number);
                  
          return num;
              }

          }



          2. 錯誤日志攔截類ExceptionAdvisor


          import org.springframework.aop.ThrowsAdvice;
          import org.springframework.aop.framework.ProxyFactory;

          import java.lang.reflect.Method;

          /**
           * Copyright 2007 GuangZhou Cotel Co. Ltd.
           * All right reserved.    
           * 異常攔截類.      
           * 
          @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
           * 
          @version 1.0 
           * Creation date: 2007-7-24 - 下午08:12:25
           
          */

          public class ExceptionAdvisor implements ThrowsAdvice {
              
          public static void main(String[] args) {
                  TestBean bean 
          = new TestBean();
                  ProxyFactory pf 
          = new ProxyFactory();
                  pf.setTarget(bean);
                  pf.addAdvice(
          new ExceptionAdvisor());

                  TestBean proxy 
          = (TestBean) pf.getProxy();
                  
          try {
                      proxy.method1();
                  }
           catch (Exception ignore) {
                  }

                  
                  
          try {
                      proxy.changeToNumber(
          "amigo");
                  }
           catch (Exception ignore) {
                  }

              }


              
          /**
               * 對未知異常的處理.
               * 
          @param method
               * 
          @param args
               * 
          @param target
               * 
          @param ex
               * 
          @throws Throwable
               * 
          @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
               * Creation date: 2007-7-24 - 下午03:35:02
               
          */

              
          public void afterThrowing(Method method, Object[] args, Object target,
                      Exception ex) 
          throws Throwable {
                  System.out.println(
          "*************************************");
                  System.out.println(
          "Error happened in class: " + target.getClass().getName());
                  System.out.println(
          "Error happened in method: " + method.getName());
                  
                  
          for (int i = 0; i < args.length; i++{
                      System.out.println(
          "arg[" + i + "]: " + args[i]);
                  }

                  
                  System.out.println(
          "Exception class: " + ex.getClass().getName());
                  System.out.println(
          "*************************************");
              }

              
              
          /**
               * 對NullPointerException異常的處理
               * 
          @param method
               * 
          @param args
               * 
          @param target
               * 
          @param ex
               * 
          @throws Throwable
               * 
          @author <a href="mailto:xiexingxing1121@126.com">AmigoXie</a>
               * Creation date: 2007-7-24 - 下午01:17:35
               
          */

              
          public void afterThrowing(Method method, Object[] args, Object target,
                      NullPointerException ex) 
          throws Throwable {
                  System.out.println(
          "*************************************");
                  System.out.println(
          "Error happened in class: " + target.getClass().getName());
                  System.out.println(
          "Error happened in method: " + method.getName());
                  
                  
          for (int i = 0; i < args.length; i++{
                      System.out.println(
          "args[" + i + "]: " + args[i]);
                  }

                  
                  System.out.println(
          "Exception class: " + ex.getClass().getName());
                  System.out.println(
          "*************************************");
              }

          }

               運行ExceptionAdvisor類后,結(jié)果如下:
               ************************************
               Error happened in class: TestBean
               Error happened in method: method1
               Exception class: java.lang.Exception
              *************************************
              *************************************
              Error happened in class: TestBean
              Error happened in method: changeToNumber
              arg[0]: amigo
              Exception class: java.lang.NumberFormatException
              *************************************

              在工程中,可將ExceptionAdvisor類作為bean定義,并指定要納入其進(jìn)行異常攔截的類。

          posted on 2007-07-24 20:36 阿蜜果 閱讀(15606) 評論(19)  編輯  收藏 所屬分類: Spring


          FeedBack:
          # re: 用spring的AOP實現(xiàn)異常攔截
          2007-07-25 03:17 | itkui
          別的不說,看你代碼就是享受。
          代碼非常優(yōu)雅。
          看一個人的代碼可以看得出一個人的為人,我相信!  回復(fù)  更多評論
            
          # re: 用spring的AOP實現(xiàn)異常攔截
          2007-07-25 08:27 | dennis
          @itkui
          這馬屁拍的也太假了吧,哈哈,玩笑

          java代碼是最沒有個人風(fēng)格的代碼,經(jīng)過一定訓(xùn)練寫出來的都一樣  回復(fù)  更多評論
            
          # re: 用spring的AOP實現(xiàn)異常攔截
          2007-07-25 08:38 | 劉遠(yuǎn)志
          >>看一個人的代碼可以看得出一個人的為人,我相信!
          呵呵,現(xiàn)在IDE都有了source format,不就天下無賊了!  回復(fù)  更多評論
            
          # re: 用spring的AOP實現(xiàn)異常攔截[未登錄]
          2007-07-25 08:48 | 阿蜜果
          @itkui
          嘿嘿,別拍我馬屁,注釋那些定義一下模版就行。
          :)  回復(fù)  更多評論
            
          # re: 用spring的AOP實現(xiàn)異常攔截
          2007-07-25 09:34 | cresposhi
          反正美女的代碼一律欣賞之,哈哈  回復(fù)  更多評論
            
          # re: 用spring的AOP實現(xiàn)異常攔截
          2007-07-25 09:46 | kenzhang
          這個問題沒遇到過,先記下。謝了  回復(fù)  更多評論
            
          # re: 用spring的AOP實現(xiàn)異常攔截
          2007-07-25 09:49 | 文溫
          @version 1.0
          這個版本號是cvs的版本號嗎?
          在模版中怎么設(shè)置呢?還有其它的cvs信息,比如 每次修改的備注信息也加到代碼中。
          我在網(wǎng)上查了一下,說是在代碼中加上@version $Id: Exp $
          就可以,我的cvs提交后確成了 @version $Id$,不知道為什么?
          我的cvs是通過eclipse提交的  回復(fù)  更多評論
            
          # re: 用spring的AOP實現(xiàn)異常攔截
          2007-07-25 10:51 | 王勇
          寫的非常好!!!
          頂一下!!!  回復(fù)  更多評論
            
          # re: 用spring的AOP實現(xiàn)異常攔截
          2007-07-25 11:24 | 一條老狗
          AOP確實非常爽。
          我就用 around 來處理 service 層的所有異常。
          然后再重新拋出JSF的 AbortProcessingException
          這樣當(dāng)出錯時,錯誤消息將顯示到用戶當(dāng)前正在操作的頁面上,而不是跳轉(zhuǎn)到專門的錯誤頁面,這樣用戶當(dāng)前的輸入值將不會丟失!

          代碼:
          public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {
          Object retVal;
          try {
          retVal = pjp.proceed();
          }
          // 楽観的ロックエラー
          catch (HibernateOptimisticLockingFailureException ex) {
          showMessage(ex, SharedMessages.error.getMessage("error.com.0087"));
          throw new AbortProcessingException(ex);
          }
          // データベース接続エラー
          catch (DataAccessResourceFailureException ex) {
          showMessage(ex, SharedMessages.other.getMessage("error.database.connection"));
          throw new AbortProcessingException(ex);
          }
          // 既にAbortProcessingException
          catch (AbortProcessingException ex) {
          showMessage(ex, null);
          throw ex;
          }
          // 他のエラー
          catch (Exception ex) {
          showMessage(ex, SharedMessages.other.getMessage("error.other"));
          throw new AbortProcessingException(ex);

          }
          return retVal;
          }  回復(fù)  更多評論
            
          # re: 用spring的AOP實現(xiàn)異常攔截
          2007-07-25 12:43 | sitinspring
          值得一看.  回復(fù)  更多評論
            
          # re: 用spring的AOP實現(xiàn)異常攔截
          2007-07-26 17:07 | Thomas
          呵呵,好文!
          P.S. 各位是來看人的?還是來看代碼的?
          o(∩_∩)o...哈哈  回復(fù)  更多評論
            
          # re: 用spring的AOP實現(xiàn)異常攔截
          2007-07-26 19:55 | 阿蜜果
          @all
          感謝各位的關(guān)注,再此謝過!

          @itkui
          優(yōu)雅的代碼應(yīng)該不止在于代碼的格式,還在于編程思想,努力ing

          @cresposhi
          還要多提建議哦!

          @一條老狗
          多謝分享!

          @Thomas
          多謝關(guān)注,別砸場子:(

            回復(fù)  更多評論
            
          # re: 用spring的AOP實現(xiàn)異常攔截
          2007-08-06 10:13 | KATEHUDSON
          用配置文件組織更好些吧  回復(fù)  更多評論
            
          # re: 用spring的AOP實現(xiàn)異常攔截
          2007-08-06 10:39 | 老虎
          學(xué)習(xí)了

          我現(xiàn)在的項目裏用了聲明式事務(wù)處理。
          ThrowsAdvice確實強大

          <tx:advice id="txAdviceDao" transaction-manager="transactionManager">
          <!-- the transactional semantics... -->
          <tx:attributes>
          <!-- all methods starting with 'find' are read-only -->
          <tx:method name="find*" read-only="true"/>
          <!-- other methods use the default transaction settings (see below) -->
          <tx:method name="update*" read-only="false" rollback-for="DataAccessException"/>
          <tx:method name="insert*" read-only="false" rollback-for="DataAccessException"/>
          <tx:method name="delete*" read-only="false" rollback-for="DataAccessException"/>
          <!-- <tx:method name="*" read-only="false" rollback-for="DataAccessException"/> -->
          </tx:attributes>
          </tx:advice>

          <aop:config proxy-target-class="true">
          <aop:pointcut id="dao" expression="execution(* com.ge.gdc.management.dao.*.*(..))"/>
          <aop:advisor pointcut-ref="dao" advice-ref="txAdviceDao"/>
          </aop:config>  回復(fù)  更多評論
            
          # re: 用spring的AOP實現(xiàn)異常攔截[未登錄]
          2007-08-06 12:22 | 阿蜜果
          @KATEHUDSON
          在項目中我當(dāng)然也用的是配置文件來組織,這里只是寫了個例子。

          @老虎
          恩,確實蠻強大  回復(fù)  更多評論
            
          # re: 用spring的AOP實現(xiàn)異常攔截
          2008-11-12 15:12 | libaiyu
          @阿蜜果
          直接導(dǎo)入jar包可能會出現(xiàn)一些It is indirectly referenced from required .class file 錯誤,剛才測試了一下,實際上需要的包如下:
          spring-aop.jar
          aopalliance.jar
          spring-core.jar
          cglib-nodep-2.1_3.jar
          commons-logging.jar  回復(fù)  更多評論
            
          # re: 用spring的AOP實現(xiàn)異常攔截[未登錄]
          2009-09-10 15:23 | zhangxu
          @阿蜜果

          貼個配置文件上來呀
            回復(fù)  更多評論
            
          # re: 用spring的AOP實現(xiàn)異常攔截[未登錄]
          2010-05-20 16:28 | sysuxk
          請問使用配置方法該如何實現(xiàn)?  回復(fù)  更多評論
            
          # re: 用spring的AOP實現(xiàn)異常攔截[未登錄]
          2011-03-31 16:37 | 111
          關(guān)鍵在于xml的配置信息,你卻沒放上來?。。  回復(fù)  更多評論
            
          <2007年7月>
          24252627282930
          1234567
          891011121314
          15161718192021
          22232425262728
          2930311234

                生活將我們磨圓,是為了讓我們滾得更遠(yuǎn)——“圓”來如此。
                我的作品:
                玩轉(zhuǎn)Axure RP  (2015年12月出版)
                

                Power Designer系統(tǒng)分析與建模實戰(zhàn)  (2015年7月出版)
                
               Struts2+Hibernate3+Spring2   (2010年5月出版)
               

          留言簿(263)

          隨筆分類

          隨筆檔案

          文章分類

          相冊

          關(guān)注blog

          積分與排名

          • 積分 - 2296376
          • 排名 - 3

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 南投市| 五华县| 章丘市| 原阳县| 双辽市| 永泰县| 灵石县| 金昌市| 仁化县| 饶阳县| 海南省| 德江县| 黄龙县| 马关县| 巴楚县| 庆阳市| 南投县| 常德市| 布尔津县| 芦山县| 特克斯县| 南川市| 资兴市| 白沙| 察隅县| 商城县| 辽宁省| 佛学| 海口市| 黄大仙区| 惠州市| 虎林市| 荣昌县| 阿瓦提县| 伊金霍洛旗| 麻江县| 民乐县| 宿迁市| 于都县| 安仁县| 炎陵县|