基于Spring项目的异常设计
1、只使用包装过的RuntimeException,不使用CheckedException。原因:Spring框架本身放弃了CheckedException这个比较有争议的异常类,而且Spring的事务管理需要捕捉RuntimeException的子类才能实现事务回滚;
2、本着简洁高效的设计原则,尽量少实现自己包装的RuntimeException子类,将异常分为几个大类包装即可,多使用最基本的继承了RuntimeException的BaseException;
3、异常只用来处理异常流程,不得用于处理正常流程。如何区分正常和异常呢?比如验证用户密码不通过、金额超过最大限度、用户名不够长等可预料的错误情况,都属于业务流程中的正常流程,而那些出乎我们预料的、不在业务流程考虑范围内但确实可以对程序的正常运行造成影响的事件,统称为异常情况(例如网络中断、硬盘空间不足),需要使用try catch做异常处理,避免造成更大的损失。这种处理由于不知道错误原因,大多数情况下可以使用简单的记录日志或强制程序终止执行的办法进行处理;
4、不允许使用一种异常类处理一种业务错误的方法处理业务逻辑。原因:系统内会产生大量的异常错误类,不便于程序员之间的配合,可能导致重复的异常错误类定义;大量的try catch语句产生的代码量并不少于if else判断,而且造成了严重的性能损失,必须坚决摒弃;
5、在抛出异常使事务回滚的过程中,异常本身同时带有错误提示信息,例如throw new BaseException("账户余额不足!"),在Action层将异常截获,并将异常内错误提示信息放入request内返回页面,由统一的页面处理程序将信息取出,并使用javascript等方式弹出显示给用户;
6、使用javascript做错误验证是不可靠的作法,用户可以使用firebug跳过javascript验证。关键性验证必须使用java代码在服务器端做验证,为了验证的快速,提升用户体验,也可以同时在页面用javascript做验证。
关于使用异常的性能问题,有很多讨论,我们可以通过测试代码检测一下使用抛异常的方式处理业务逻辑到底会有多大的性能损失。以下代码摘抄自《透过JVM看 Exception本质》[url]http://www.iteye.com/topic/857722[/url],这篇文章分析的很专业,建议看一下。
运行结果:
[quote]
建立对象:575817
建立异常对象:9589080
建立、抛出并接住异常对象:4739447
[/quote]
所以我们说使用抛异常的方式处理业务逻辑会造成大量性能损失,这个性能损失的数量级一般要超过正常处理的10倍。
1、只使用包装过的RuntimeException,不使用CheckedException。原因:Spring框架本身放弃了CheckedException这个比较有争议的异常类,而且Spring的事务管理需要捕捉RuntimeException的子类才能实现事务回滚;
2、本着简洁高效的设计原则,尽量少实现自己包装的RuntimeException子类,将异常分为几个大类包装即可,多使用最基本的继承了RuntimeException的BaseException;
3、异常只用来处理异常流程,不得用于处理正常流程。如何区分正常和异常呢?比如验证用户密码不通过、金额超过最大限度、用户名不够长等可预料的错误情况,都属于业务流程中的正常流程,而那些出乎我们预料的、不在业务流程考虑范围内但确实可以对程序的正常运行造成影响的事件,统称为异常情况(例如网络中断、硬盘空间不足),需要使用try catch做异常处理,避免造成更大的损失。这种处理由于不知道错误原因,大多数情况下可以使用简单的记录日志或强制程序终止执行的办法进行处理;
4、不允许使用一种异常类处理一种业务错误的方法处理业务逻辑。原因:系统内会产生大量的异常错误类,不便于程序员之间的配合,可能导致重复的异常错误类定义;大量的try catch语句产生的代码量并不少于if else判断,而且造成了严重的性能损失,必须坚决摒弃;
5、在抛出异常使事务回滚的过程中,异常本身同时带有错误提示信息,例如throw new BaseException("账户余额不足!"),在Action层将异常截获,并将异常内错误提示信息放入request内返回页面,由统一的页面处理程序将信息取出,并使用javascript等方式弹出显示给用户;
6、使用javascript做错误验证是不可靠的作法,用户可以使用firebug跳过javascript验证。关键性验证必须使用java代码在服务器端做验证,为了验证的快速,提升用户体验,也可以同时在页面用javascript做验证。
关于使用异常的性能问题,有很多讨论,我们可以通过测试代码检测一下使用抛异常的方式处理业务逻辑到底会有多大的性能损失。以下代码摘抄自《透过JVM看 Exception本质》[url]http://www.iteye.com/topic/857722[/url],这篇文章分析的很专业,建议看一下。
package org.fenixsoft.exception;
public class ExceptionTest {
private int testTimes;
public ExceptionTest(int testTimes) {
this.testTimes = testTimes;
}
public void newObject() {
long l = System.nanoTime();
for (int i = 0; i < testTimes; i++) {
new Object();
}
System.out.println("建立对象:" + (System.nanoTime() - l));
}
public void newException() {
long l = System.nanoTime();
for (int i = 0; i < testTimes; i++) {
new Exception();
}
System.out.println("建立异常对象:" + (System.nanoTime() - l));
}
public void catchException() {
long l = System.nanoTime();
for (int i = 0; i < testTimes; i++) {
try {
throw new Exception();
} catch (Exception e) {
}
}
System.out.println("建立、抛出并接住异常对象:" + (System.nanoTime() - l));
}
public static void main(String[] args) {
ExceptionTest test = new ExceptionTest(10000);
test.newObject();
test.newException();
test.catchException();
}
}
运行结果:
[quote]
建立对象:575817
建立异常对象:9589080
建立、抛出并接住异常对象:4739447
[/quote]
所以我们说使用抛异常的方式处理业务逻辑会造成大量性能损失,这个性能损失的数量级一般要超过正常处理的10倍。