背景
这篇文章介绍的异常处理思路不错,本文试图给出一种具体实现,当然可能和作者的思路有所不同。
框架介绍
关于异常的一些想法:
异常不能跨越“边界类”。
在边界类之下,异步不能被“吞掉”。
系统在不同场景或分层中,需要的不同的处理“策略”。
每种策略都是一个可扩展的“管道”。
可以和 AOP 进行集成。
异常可以用来给业务用户提供“提醒”。
异常可以给运维用户提供“日志”。
我希望异常处理框架以某种机制支持上面的各种想法。
针对边界类的处理场景
模拟的边界类
1 package com.happyframework.exception.handling;2
3 import org.springframework.stereotype.Controller;4
5 import com.happyframework.exception.handling.springframework.HandleException;6
7 @Controller8 public classTestController {9
10 @HandleException("UI")11 public voidtest() {12 throw new RuntimeException("业务失败");13 }14
15 }
因为边界类需要特殊的异常处理策略,这里指定了的策略名字为:“UI”。
“UI”策略对应的管道配置
1 <?xml version="1.0" encoding="UTF-8"?>
2
3 xmlns:xsi="外链网址已屏蔽"
4 xmlns:p="外链网址已屏蔽"
5 xmlns:context="外链网址已屏蔽"
6 xmlns:mvc="外链网址已屏蔽"
7 xmlns:aop="外链网址已屏蔽"
8 xmlns:util="外链网址已屏蔽"
9 xsi:schemaLocation="外链网址已屏蔽10 外链网址已屏蔽11 外链网址已屏蔽12 外链网址已屏蔽13 外链网址已屏蔽14 外链网址已屏蔽15 外链网址已屏蔽16 外链网址已屏蔽17 外链网址已屏蔽18 外链网址已屏蔽">
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
为管道定义了两个处理器:日志处理器和提醒处理器,因为是测试的处理器,实现就比较简单,真实项目中可以决定:哪些异常需要日志?哪些信息提醒给用户?
运行输出
1 记录日志:java.lang.RuntimeException: 业务失败2 提示消息:java.lang.RuntimeException: 业务失败
“UI”策略导致异常被吞掉了,这也是我们期望的行为,后面会介绍如何在处理器中吞掉异常。
核心 API 介绍
主要类型
代码可以去 外链网址已屏蔽 下载。
重点说一下 ExceptionHandlerChain
1 packagecom.happyframework.exception.handling;2
3 public interfaceExceptionHandlerChain {4
5 Throwable getException();6
7 void setNewException(finalThrowable newException);8
9 booleanisExceptionHandled();10
11 void setExceptionHandled(final booleanexceptionHandled);12
13 voidproceed();14
15 }
ExceptionHandlerChain 是作为参数传递给 ExceptionHandler:
1 packagecom.happyframework.exception.handling;2
3 public interfaceExceptionHandler {4
5 void handle(finalExceptionHandlerChain chain);6
7 }
ExceptionHandlerChain 的成员的主要意图是:
Throwable getException():返回正在处理的异常。
void setNewException(final Throwable newException):替换或包装异常的时候调用此方法。
boolean isExceptionHandled():异常是否被处理过。
void setExceptionHandled(final boolean exceptionHandled):吞掉异常的时候调用此方法。
void proceed():执行下一个处理器。
一个简单的异常处理器
1 packagecom.happyframework.exception.handling;2
3 final class ConsoleNotificationHandler implementsExceptionHandler {4
5 @Override6 public final void handle(finalExceptionHandlerChain chain) {7 System.out.println("提示消息:" +chain.getException());8
9 chain.setExceptionHandled(true);10 chain.proceed();11 }12
13 }
备注
第一次用 Java 写东西,感觉挺不错的。