Java:使用 Java 開發的一個異常處理框架


背景

這篇文章介紹的異常處理思路不錯,本文試圖給出一種具體實現,當然可能和作者的思路有所不同。

框架地址:https://github.com/happyframework/HappyFramework

框架介紹

關於異常的一些想法:

  1. 異常不能跨越“邊界類”。
  2. 在邊界類之下,異步不能被“吞掉”。
  3. 系統在不同場景或分層中,需要的不同的處理“策略”。
  4. 每種策略都是一個可擴展的“管道”。
  5. 可以和 AOP 進行集成。
  6. 異常可以用來給業務用戶提供“提醒”。
  7. 異常可以給運維用戶提供“日志”。

我希望異常處理框架以某種機制支持上面的各種想法。

針對邊界類的處理場景

模擬的邊界類

 1 package com.happyframework.exception.handling;
 2 
 3 import org.springframework.stereotype.Controller;
 4 
 5 import com.happyframework.exception.handling.springframework.HandleException;
 6 
 7 @Controller
 8 public class TestController {
 9 
10     @HandleException("UI")
11     public void test() {
12         throw new RuntimeException("業務失敗");
13     }
14     
15 }

因為邊界類需要特殊的異常處理策略,這里指定了的策略名字為:“UI”。

“UI”策略對應的管道配置

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4        xmlns:p="http://www.springframework.org/schema/p"
 5        xmlns:context="http://www.springframework.org/schema/context"
 6        xmlns:mvc="http://www.springframework.org/schema/mvc"
 7        xmlns:aop="http://www.springframework.org/schema/aop"
 8        xmlns:util="http://www.springframework.org/schema/util"
 9        xsi:schemaLocation="http://www.springframework.org/schema/beans 
10                            http://www.springframework.org/schema/beans/spring-beans.xsd
11                            http://www.springframework.org/schema/context 
12                            http://www.springframework.org/schema/context/spring-context.xsd
13                            http://www.springframework.org/schema/mvc
14                            http://www.springframework.org/schema/mvc/spring-mvc.xsd
15                            http://www.springframework.org/schema/aop
16                            http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
17                            http://www.springframework.org/schema/util
18                             http://www.springframework.org/schema/util/spring-util-3.0.xsd">
19 
20     <context:component-scan base-package="com.happyframework.exception.handling.springframework" />
21     <context:component-scan base-package="com.happyframework.exception.handling" />
22     
23     <aop:aspectj-autoproxy/>
24 
25      <bean class="com.happyframework.exception.handling.springframework.ExceptionHandlerDefination">
26         <property name="policy" value="UI"/>
27         <property name="handler">
28             <bean class="com.happyframework.exception.handling.ConsoleLoggingHandler"/>
29         </property>
30     </bean>
31      <bean class="com.happyframework.exception.handling.springframework.ExceptionHandlerDefination">
32         <property name="policy" value="UI"/>
33         <property name="handler">
34             <bean class="com.happyframework.exception.handling.ConsoleNotificationHandler"/>
35         </property>
36     </bean>
37 </beans>
38          

為管道定義了兩個處理器:日志處理器和提醒處理器,因為是測試的處理器,實現就比較簡單,真實項目中可以決定:哪些異常需要日志?哪些信息提醒給用戶?

運行輸出

1 記錄日志:java.lang.RuntimeException: 業務失敗
2 提示消息:java.lang.RuntimeException: 業務失敗

“UI”策略導致異常被吞掉了,這也是我們期望的行為,后面會介紹如何在處理器中吞掉異常。

核心 API 介紹

主要類型

代碼可以去 https://github.com/happyframework/HappyFramework 下載。

重點說一下 ExceptionHandlerChain

 1 package com.happyframework.exception.handling;
 2 
 3 public interface ExceptionHandlerChain {
 4 
 5     Throwable getException();
 6 
 7     void setNewException(final Throwable newException);
 8 
 9     boolean isExceptionHandled();
10 
11     void setExceptionHandled(final boolean exceptionHandled);
12 
13     void proceed();
14 
15 }

ExceptionHandlerChain 是作為參數傳遞給 ExceptionHandler:

1 package com.happyframework.exception.handling;
2 
3 public interface ExceptionHandler {
4 
5     void handle(final ExceptionHandlerChain chain);
6 
7 }

ExceptionHandlerChain 的成員的主要意圖是:

  1. Throwable getException():返回正在處理的異常。
  2. void setNewException(final Throwable newException):替換或包裝異常的時候調用此方法。
  3. boolean isExceptionHandled():異常是否被處理過。
  4. void setExceptionHandled(final boolean exceptionHandled):吞掉異常的時候調用此方法。
  5. void proceed():執行下一個處理器。

一個簡單的異常處理器

 1 package com.happyframework.exception.handling;
 2 
 3 final class ConsoleNotificationHandler implements ExceptionHandler {
 4 
 5     @Override
 6     public final void handle(final ExceptionHandlerChain chain) {
 7         System.out.println("提示消息:" + chain.getException());
 8 
 9         chain.setExceptionHandled(true);
10         chain.proceed();
11     }
12 
13 }

備注

第一次用 Java 寫東西,感覺挺不錯的。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM