背景

这篇文章介绍的异常处理思路不错,本文试图给出一种具体实现,当然可能和作者的思路有所不同。

框架地址: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>

为管道定义了两个处理器:日志处理器和提醒处理器,因为是测试的处理器,实现就比较简单,真实项目中可以决定:哪些异常需要日志?哪些信息提醒给用户?

运行输出

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

备注

第一次用 Java 写东西,感觉挺不错的。

Java:使用 Java 开发的一个异常处理框架的更多相关文章

  1. 在做java 的web开发,为什么要使用框架

    现在做项目都会使用框架,现在很常见的框架就是SSH(Struts+SpringMVC+spring+hibernate),SSM(Struts/springMVC+Spring+Hibernate), ...

  2. java前后端开发需掌握的框架及技术

    一.Java开发 1.J2EE架构及主流框架,spring4.spring boot.spring MVC.spring Security.spring cloud.struct2.hibernate ...

  3. 基于Spring开发的一个BIO-RPC框架(对新人很友好)

    PART1:先来整体看下项目的构成 其中bio-rpc-core就是所谓的rpc框架 bio-rpc-example-client即所谓的服务调用方(你的项目中想要调用服务的地方) bio-rpc-e ...

  4. 关于JAVA项目中的常用的异常处理情况总结

    1. JAVA异常处理 在面向过程式的编程语言中,我们可以通过返回值来确定方法是否正常执行.比如在一个c语言编写的程序中,如果方法正确的执行则返回1.错误则返回0.在vb或delphi开发的应用程序中 ...

  5. 俯瞰 Java 服务端开发

    原文首发于 github ,欢迎 star . Java 服务端开发是一个非常宽广的领域,要概括其全貌,即使是几本书也讲不完,该文将会提到许多的技术及工具,但不会深入去讲解,旨在以一个俯瞰的视角去探寻 ...

  6. 从头实现一个koa框架

    koajs是最流行的nodejs后端框架之一,有很多网站都使用koa进行开发,同时社区也涌现出了一大批基于koa封装的企业级框架.然而,在这些亮眼的成绩背后,作为核心引擎的koa代码库本身,却非常的精 ...

  7. 深入探索 高效的Java异常处理框架

    转载自:http://www.sunwei.org/archives/196 摘要:本文从Java异常最基本的概念.语法开始讲述了Java异常处理的基本知识,分析了Java异常体系结构,对比Sprin ...

  8. 为什么做java的web开发我们会使用struts2,springMVC和spring这样的框架?

    今年我一直在思考web开发里的前后端分离的问题,到了现在也颇有点心得了,随着这个问题的深入,再加以现在公司很多web项目的控制层的技术框架由struts2迁移到springMVC,我突然有了一个新的疑 ...

  9. java web后台开发SSM框架(Spring+SpringMVC+MyBaitis)搭建与优化

    一.ssm框架搭建 1.1创建项目 新建项目后规划好各层的包. 1.2导入包 搭建SSM框架所需包百度云链接:http://pan.baidu.com/s/1cvKjL0 1.3整合spring与my ...

随机推荐

  1. DedeCms当前位置导航去掉最后的分隔符>

    DedeCms的当前位置导航调用标签{dede:field name=’position’ /},在栏目页里调用的当前位置导航,最后会出现分割符号“>”,如:主页 > DedeCms 模板 ...

  2. MVC公开课 – 2.查询,删除 (2013-3-15广州传智MVC公开课)

    查询 /Controller/HomeController.cs /// <summary> /// 查询 文章 列表 /// </summary> /// <retur ...

  3. AC日记——小A和uim之大逃离 II 洛谷七月月赛

    小A和uim之大逃离 II 思路: spfa: 代码: #include <bits/stdc++.h> using namespace std; #define INF 0x3f3f3f ...

  4. vue引入自己写的js文件

    话不多说,直接上代码呀~ 先来个结构图: 中规中矩的vue-cli就写了一个自己的js文件 那么我想要引入到vue组件里. 1.首先写我的js文件 2.引入到vue组件!!!一定要用{}把方法名拿过来 ...

  5. python爬虫实战(六)--------新浪微博(爬取微博帐号所发内容,不爬取历史内容)

    相关代码已经修改调试成功----2017-4-13 详情代码请移步我的github:https://github.com/pujinxiao/sina_spider 一.说明 1.目标网址:新浪微博 ...

  6. 湖南大学ACM程序设计新生杯大赛(同步赛)D - Number

    题目描述 We define Shuaishuai-Number as a number which is the sum of a prime square(平方), prime cube(立方), ...

  7. CodeForces 785C Anton and Fairy Tale

    二分. 如果$n≤m$,显然只能$n$天. 如果$n>m$,至少可以$m$天,剩余还可以支撑多少天,可以二分计算得到,也可以推公式.二分计算的话可能爆$long$ $long$,上了个$Java ...

  8. quartz定时任务,已过期的内容自动下线

    概念: Quartz是一个开源的作业调度框架,可以让计划的程序任务一个预定义的日期和时间运行.Quartz可以用来创建简单或复杂的日程安排执行几十,几百,甚至是十万的作业数. 框架架构: 简单实例: ...

  9. 洛谷——P2071 座位安排 seat.cpp/c/pas

    P2071 座位安排 seat.cpp/c/pas 题目背景 公元二零一四年四月十七日,小明参加了省赛,在一路上,他遇到了许多问题,请你帮他解决. 题目描述 已知车上有N排座位,有N*2个人参加省赛, ...

  10. CentOS 报错cannot execute binary file

    在安装软件过程中执行文件,报错cannot execute binary file 1.查看是否root用户登录,当前用户是否有可执行权限 2.ls -l 查看文件是否具有可执行权限 3.要使用对应的 ...