题记
最近两天在思考java中的异常机制
以前做项目的过程中我们并没有在意对异常的处理:
/**
*
* 比如doSomeThing()负责底层的业务逻辑(比如打开数据库连接或者读取文件)
* 由于SQLException, IOException属于检查异常所以我们必须捕获处理
* 所以我们的通用做法就是将SQLException, IOException转译成自定义异常
* 根据doSomeThing()发生的异常信息抛给上层处理;
*/
try {
doSomeThing();
}catch(SQLException e | IOException | ...) {
//抛出自定义异常给上层
throw new MyException("exception cause...", e);
}
这样做貌似没有什么问题
但是仔细想一下你抛给上层,那上层怎么处理(是否是依旧在某个代码块通过try-catch来捕获处理)
如果只是这样处理的话,那我们的catch块中将会导致大量的重复代码
并且大量异常处理程序置于catch块中造成程序的高耦合性
异常处理框架
概念
首先我们需要了解几个概念:
- 异常是什么?
- 非检查异常与检查异常?
- 异常转译
- 异常链与异常丢失
由于之前查资料的时候网上有许多清晰明朗的见解(关于这四个问题)
我在这放几个传送门(关于这四个问题):
实现异常处理框架
首先非常感谢HappyFramework(幸福框架)这位博主的奉献
关于异常处理框架的探究请参考:
我只是对此做了一个简化与剖析
首先来看下处理框架类图:
基本思路如下:
- 1.客户端(比喻成你的代码块)发生异常,这时候我们需要捕获处理或者选择向上抛出
- 2.这里我们设计一个异常处理业务类专门来处理异常(ExceptionService)
- 3.我们现在有一个统一的异常业务类(比喻成一个大管家,只是做一个异常处理请求的分发)
- 4.所以我们还需要自定义异常处理器(ExceptionHandler)来处理对应的异常
- 5.现在比如有一个异常发生了,但是我们需要在多个地方使用不同的自定义处理器来进行处理
- 6.所以我们需要一个异常处理链(ExceptionHandlerChain)来对ExceptionHandler处理器进行管理
- 7.最后自定义处理器处理异常之后,我们需要一个处理结果(ExceptionHandlerResult)
由于篇幅限制,我在这列出3个核心类的实现
运行效果如图:
具体实现(简化版)如下:
首先来看客户端(ProxyClass_Test):
/**
* Created by antsmarth on 15-8-26.
*
* 单元测试类:
*
* 测试TestExceptionBean
*
*
*/
public class ProxyClass_Test {
@Test
public void proxy_test() throws Throwable {
//初始化ExceptionService方法
InitExceptionService exceptionService = new InitExceptionService();
//创建测试Bean
TestExceptionBean_Inter test_bean = new TestExceptionBean();
try {
//调用测试方法
test_bean.test_exception();
}catch(Throwable throwable) {
//接受异常并交给ExceptionService类处理
exceptionService.getExceptionService().handler("user", throwable, "default").autoRunException();
}
}
}
之后我们来看大管家(ExceptionService –> DefaultExceptionService)的具体实现:
package cn.march.model.exception.framework.default_impl;
import cn.march.model.exception.framework.ExceptionHandler;
import cn.march.model.exception.framework.ExceptionHandlerChain;
import cn.march.model.exception.framework.ExceptionHandlerResult;
import cn.march.model.exception.framework.ExceptionService;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Created by antsmarth on 15-8-26.
*
* 默认异常业务处理逻辑实现类:
* 继承于ExceptionService接口
* 通过接受从客户端捕获到的异常对象,和处理策略
* 初始化自定义异常处理类,与处理策略相关联(Map<String, List<ExceptionHandler>>)
* 通过调用ExceptionHandlerChain处理链完成实际的业务操作
*/
public class DefaultExceptionService implements ExceptionService{
//处理策略,自定义异常处理类集合
private Map<String, List<ExceptionHandler>> policy_handlers = null;
//异常处理责任链
private ExceptionHandlerChain chain = null;
//构造方法
public DefaultExceptionService(int cap) {
policy_handlers = new HashMap<>(cap);
}
public DefaultExceptionService() {
this(1);
}
/**
* 实际的处理业务方法:
* 接受从客户端传递过来的处理策略:String policy
* 捕获异常:Throwable exception
* 调用默认异常处理链的处理方法: DefaultExceptionHandlerChain.proceed();
* 返回异常处理结果;
*
* @param policy : 处理策略
* @param exception : 捕获异常
* @return ExceptionHandlerResult
*/
@Override
public ExceptionHandlerResult handler(String policy, Throwable exception, String chain_type) {
switch (chain_type) {
case "default" :
chain = new DefaultExceptionHandlerChain(this.getPolicyHandler(policy),exception);
break;
case "other" :
System.out.println("nothing chain found...");
break;
default:
break;
}
if(null == chain)
throw new RuntimeException("请检查异常处理链类是否配置或者存在...");
chain.proceed();
return chain.createExceptionHandlerResult();
}
/**
* 向某个具体的处理策略添加指定的异常处理器
*
* @param policy
* @param handler
* @return
*/
@Override
public ExceptionService registerHandler(String policy, ExceptionHandler handler) {
this.getPolicyHandler(policy).add(handler);
return this;
}
/**
* 获取某个处理策略的异常处理器集合
*
* @param policy
* @return
*/
private List<ExceptionHandler> getPolicyHandler(String policy) {
if(!policy_handlers.containsKey(policy))
policy_handlers.put(policy, new ArrayList<ExceptionHandler>(2));
return policy_handlers.get(policy);
}
}
ExceptionHandlerChain –> DefaultExceptionHandlerChain的实现:
package cn.march.model.exception.framework.default_impl;
import cn.march.model.exception.framework.ExceptionHandler;
import cn.march.model.exception.framework.ExceptionHandlerChain;
import cn.march.model.exception.framework.ExceptionHandlerResult;
import java.util.List;
/**
* Created by antsmarth on 15-8-26.
* 类的职责:
* 默认异常处理链的实现类
* 类中包括自定义异常处理类的集合 handlers : List<ExceptionHandler>
* 需要捕获处理的异常 exception : Throwable
* 需要转译的新的异常 new_exception : Throwable
* 异常是否需要抛出 exceptionHandler : boolean
*
*/
public class DefaultExceptionHandlerChain implements ExceptionHandlerChain {
//自定义异常处理类集合
private List<ExceptionHandler> handlers = null;
//当前异常处理器游标
private int currentHandlerIndex = 0;
//捕获异常
private Throwable exception;
//转译异常
private Throwable new_exception;
//异常是否抛出
private boolean exceptionHandler;
//构造方法,通过传入自定义异常处理类集合和捕获异常构造对象
public DefaultExceptionHandlerChain(List<ExceptionHandler> handlers, Throwable exception) {
this.handlers = handlers;
this.exception = exception;
}
@Override
public Throwable getException() {
return this.exception;
}
@Override
public void setException(Throwable exception) {
this.setExceptionHandler(true);
this.new_exception = exception;
}
@Override
public boolean isExceptionHandler() {
return this.exceptionHandler;
}
@Override
public void setExceptionHandler(boolean exceptionHandler) {
this.exceptionHandler = exceptionHandler;
}
/**
* 异常处理方法:
* 遍历自定义异常处理类集合,调用处理方法
*/
@Override
public void proceed() {
while(canProceed()) {
this.getCurrentExceptionHandler().handler(this);
currentHandlerIndex++;
}
}
/**
* 通过捕获异常与转译异常和是否抛出异常标志位,创建异常处理结果类;
* @return ExceptionHandlerResult : result
*/
public ExceptionHandlerResult createExceptionHandlerResult() {
return new ExceptionHandlerResult(this.exception, this.new_exception, this.exceptionHandler);
}
/**
* 判断处理类集合是否遍历完成
* @return boolean : flag
*/
private boolean canProceed() {
return this.currentHandlerIndex <= handlers.size() - 1;
}
/**
* 通过当前处理类游标获取实际的异常处理类
* @return ExceptionHandler : handler
*/
private ExceptionHandler getCurrentExceptionHandler() {
return this.handlers.get(this.currentHandlerIndex);
}
}