异常处理框架

Nov 1, 2016


题记

最近两天在思考java中的异常机制

以前做项目的过程中我们并没有在意对异常的处理:

/**
 *
 * 比如doSomeThing()负责底层的业务逻辑(比如打开数据库连接或者读取文件)
 * 由于SQLException, IOException属于检查异常所以我们必须捕获处理
 * 所以我们的通用做法就是将SQLException, IOException转译成自定义异常
 * 根据doSomeThing()发生的异常信息抛给上层处理;
 */
try {

	doSomeThing();		

}catch(SQLException e | IOException | ...) {
	
	//抛出自定义异常给上层
	throw new MyException("exception cause...", e);

}

这样做貌似没有什么问题

但是仔细想一下你抛给上层,那上层怎么处理(是否是依旧在某个代码块通过try-catch来捕获处理)

如果只是这样处理的话,那我们的catch块中将会导致大量的重复代码

并且大量异常处理程序置于catch块中造成程序的高耦合性

异常处理框架

概念

首先我们需要了解几个概念:

  • 异常是什么?
  • 非检查异常与检查异常?
  • 异常转译
  • 异常链与异常丢失

由于之前查资料的时候网上有许多清晰明朗的见解(关于这四个问题)

我在这放几个传送门(关于这四个问题):

实现异常处理框架

首先非常感谢HappyFramework(幸福框架)这位博主的奉献

关于异常处理框架的探究请参考:

我只是对此做了一个简化与剖析

首先来看下处理框架类图:

exceptionFramework

基本思路如下:

  • 1.客户端(比喻成你的代码块)发生异常,这时候我们需要捕获处理或者选择向上抛出
  • 2.这里我们设计一个异常处理业务类专门来处理异常(ExceptionService)
  • 3.我们现在有一个统一的异常业务类(比喻成一个大管家,只是做一个异常处理请求的分发)
  • 4.所以我们还需要自定义异常处理器(ExceptionHandler)来处理对应的异常
  • 5.现在比如有一个异常发生了,但是我们需要在多个地方使用不同的自定义处理器来进行处理
  • 6.所以我们需要一个异常处理链(ExceptionHandlerChain)来对ExceptionHandler处理器进行管理
  • 7.最后自定义处理器处理异常之后,我们需要一个处理结果(ExceptionHandlerResult)

由于篇幅限制,我在这列出3个核心类的实现

运行效果如图:

exception_test

具体实现(简化版)如下:

首先来看客户端(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);
    }

}