javaWeb项目使用aop处理异常?

dongcx1234567
  • 224

1.dao层我是直接抛出异常,都是比较“底层”的异常,比如DataAccessException. 不捕获的原因是,假如service调用了多个dao方法,其中有一个发生了异常,如果该dao方法自己捕获了又没有重新抛出来。这时候,service事务没法回滚,因为它以为都执行正确了。
2.在service里, 调用的dao方法有可能抛出DataAccessException的话,那么service也不捕获。因为DataAccessException是runtime异常,无需强制try-catch,况且,如果你捕获了又没有抛出来,配置的事务没法感知到,因为默认只处理runtime异常,当然可以配置。
3.还可以这样,在service方法里,dao方法外面直接try-catch(Throwable e). 然后重新抛出自定义的业务相关的异常。比如TopicUpdateException.

问题:上面1,2,3我对dao层,service层的方法处理是否合理。2,3哪种更好些?为什么?

4.接上面,这个自定义的业务异常的粒度要控制到什么级别?能否举个例子
5.上面2,3 我都是用的aop统一处理异常。我看大部分人也推荐这么做。因为service层各个方法里catch里的逻辑大都相似。使用aop统一处理,好处是显而易见的。我想知道,有什么弊端吗?因为我发现公司项目几乎没有这么做的。都是直接try-catch,返回结果。要么就是上面2里提到的不捕获。出了异常反正可以记录在log里

请大家帮忙看看

回复
阅读 6.4k
4 个回答
✓ 已被采纳

谢邀! 不过我得声明我不是专家|_|

问题:上面1,2,3我对dao层,service层的方法处理是否合理。2,3哪种更好些?

首先我赞同你在1, 2, 3步里的分析和理解。其次,我认为3的处理更为妥帖,因为service层就已经不是纯粹的数据交互,而是包含了一系列业务逻辑的操作,通过捕获Throwable然后再抛出更有意义的(能准确描述错误的)异常,无论是记入日志还是事物处理,这个对于后续可能存在的补救/错误排查更合适

4.接上面,这个自定义的业务异常的粒度要控制到什么级别?能否举个例子

粒度取决于需求,譬如你只想做回滚,那么只要能够定位到什么service错了对你来说就够了。但如果还希望进一步排查root cause,那是不是异常信息里再多一些关于源错误的描述更好些?

5.上面2,3 我都是用的aop统一处理异常。我看大部分人也推荐这么做。因为service层各个方法里catch里的逻辑大都相似。使用aop统一处理,好处是显而易见的。我想知道,有什么弊端吗?因为我发现公司项目几乎没有这么做的。都是直接try-catch,返回结果。要么就是上面2里提到的不捕获。出了异常反正可以记录在log里

首先谈你们公司为什么没那么做,这可能是历史原因,之前搭建框架的人对aop认识不足,或者把个人喜好带到了工作中导致选择了直接到处try catch(这种方式简单粗暴,最易掌握),aop是算是一种设计范式,无论架构师还是程序员,要想熟练掌握并且运用自如还是需要学习成本的(这可能算是弊端吧)。如果你对原因感兴趣,最好找几个老资格同事私底下聊聊看,说不定好能套出些其他内幕^^

关于"出了异常反正可以记录在log里",想法没有错,但真的在海量日志里处理过错误信息的人是会有体会的。明明可以统一处理,却没做,这算是设计缺陷或者失误。不是解决问题最有效的方案

我是外行,轻点拍砖^^

使用Spring AOP对异常进行统一处理,当然是第三种方法更好了。使用Spring AOP对serivce层抛出的异常进行拦截,记录所有未处理的异常日志,并将所有未处理异常转换成统一自定义的系统异常,以便让controller层或Rpc层能够将这些自定义的异常信息反馈到前端,在浏览器端进行展示。
不要忘了,使用Spring AOP对异常进行拦截,其真正作用是实现:将异常的处理逻辑和正常的处理逻辑进行解耦。所以你说异常的粒度控制在什么级别?这个是根据你的业务逻辑来的。诸如,操作数据库增删改查失败?调用外部接口失败?其他异常信息等等。 
你们公司的方式是不规范的,不合适的。处理日志时,需要在每一个try-catch块包含一些处理代码,有时候异常处理的代码比正常执行代码还多,污染正常执行代码。 异常处理代码散落,修改起来时非常麻烦。无法对某些异常进行统一处理和修改。
Service中的业务方法命名不按照事前定义好的规则进行命名的话,AOP是拦截不到的。也就是说事务控制是无法加载的。这些命名的规范什么的需要在配置文件中指定。

我们都是在controller层做aop异常处理的
异常分为非ajax异常和ajax异常, 因为我们是使用jquery,没有做到前后端完全分离,有的前端数据是后端直接渲染

  1. ajax异常: 在header中包含X-Requested-With来判断

  2. 非ajax异常: ajax异常之外的
    肯定你前台显示给客户错误的方式是不同的, 所以在Interceptor(filter)(aop)中分别处理

在service类的每个方法中, 没有说整个用try catch包住的, 太二了,异常分为你控制不了的比如数据库异常,空指针什么的, 这些都不用catch的, 在service中是根据业务中的异常业务抛出, 比如用户名重复了, 我就throw 一个BizException("用户名重复"),其中BizException是继承了RuntimeException的

lz说的aop来处理异常, 我不知道你是在service层还是controller层, 显然按照我上面的分析应该是在controller层做的

如果我这个不是最佳答案,就太没天理了

你是用spring mvc的吧?spring mvc有全局的异常处理,你可以去搜下,具体的我在手机上不能方便的表达出来。

宣传栏