这个题目可能有些危言悚听,使用Spring的同行不用害怕,只是因为工作中碰到一些问题,才偶然想到这个问题。
首先要明确两个问题:
1、系统隔离原则:
即系统间依赖应该是清晰的,不因为一个系统的故障影响其他系统,甚至整个系统。
2、简单应用习惯:
普通程序员只会处理checked Exception,负责任的程序员会处理被调用的函数可能抛出的异常(根据源码或javadoc)
我们碰到一个情况:
使用Spring的 init 特性初试化一个bean--一个使用Qutarz的调度程序。初试化过程中会抛出RuntimeException,从而造成Spring容器的整个初试化失败。首先我们修改了程序,捕获了所有异常,随后在编码指南中加入了一句话:"所有使用Spring-init机制初试化的类必须在init中捕获所有异常:Exception"。因为只有如此才能保证整个系统不会因为局部问题而完全瘫痪。
我觉得这是Spring对异常处理的一个悖论:
正方:底层异常都封装成Runtime的,经过几次包装--->简单应用习惯--->异常被抛出领域层(init场景下:由Spring处理)
反方: 一个类的失败可以造成整个系统的失败---->Spring被RuntimeException宕掉---->不符合系统隔离原则
当然充分的测试可能可以解决这个问题:但是要注意,测试只能证明系统有bug,不能证明系统没有bug。
解决方案:
1、好的设计习惯:将应该隔离的系统隔离开-->使用不同的Spring配置文件.
2、接口层错误处理:在接口层应该尽量对可以处理的异常进行处理,然后以合理的方式传递给上层.
PS:在与人交互的系统中都应该给最终用户合理的错误提示,所以表现层应该尽量捕获非业务的RuntimeException给最终用户更好的操作感受。