Java全局异常处理器实现过程解析
前⾔
最近稍微闲了⼀点于是把这个半年都没更新的开源项⽬重新捡了起来。
⼀些新关注的朋友应该还不知道这项⽬是⼲啥的?先来看看官⽅介绍吧(其实就我⾃⼰写的 )
cicada: 基于 Netty4 实现的快速、轻量级 WEB 框架;没有过多的依赖,核⼼ jar 包仅 30KB。
效果
⼴告打完了,回到正题;⼤家平时最常⽤的 MVC 框架当属 SpringMVC 了,⽽在搭建脚⼿架的时候相信全局异常处理是必不可少的。
Spring ⽤法
通常我们的做法如下:
传统 Spring 版本:
实现⼀个 Spring ⾃带的接⼝,重写其中的⽅法,最后的异常处理便在此处。将这个类配置在 Spring 的 xml ,当做⼀个 bean 注册到 Spring 容器中。
public class CustomExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) {
//⾃定义处理
}
<bean class="ption.CustomExceptionResolver"></bean>
当然现在流⾏的 SpringBoot 也有对应的简化版本:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(value = Exception.class)
springmvc面试复习
public Object defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {
//⾃定义处理
}
}
全部都换为注解形式,但本质上还是⼀样的。
都是要在容器中创建⼀个特殊的 bean,这个 bean 专门⽤于处理异常,当系统运⾏时出现异常,就从容器中到该 bean,并执⾏其中的⽅法即可。
⾄于这个特殊的 bean 如何标识出来,⽆⾮就是实现某个特定接⼝或者⽤注解声明,也就对应了传统 Spring 和 SpringBoot 的⽤法。
cicada ⽤法
cicada 在设计⾃⼰的全局异常处理器时也参考了 Spring 的相关设计,所以最终⽤法如下:
@CicadaBean
public class ExceptionHandle implements GlobalHandelException {
private final static Logger LOGGER = Logger(ExceptionHandle.class);
@Override
public void resolveException(CicadaContext context, Exception e) {
<("Exception", e);
WorkRes workRes = new WorkRes();
workRes.setCode("500");
workRes.Class().getName() + "系统运⾏出现异常");
context.json(workRes);
}
}
⾃定义⼀个实现了 GlobalHandelException 接⼝的类,当请求出现异常时,页⾯和后台将会如下输出:
设计
看得出⽤法和 Spring ⾮常类似,也是需要实现⼀个接⼝ GlobalHandelException,同时使⽤ @CicadaBean 注解该类将他加载到 cicada 内置的IOC 容器内。
当出现异常时则在这个 IOC 容器中到该对象调⽤它的 resolveException 即可。
其中还可以通过 CicadaContext 全局上下⽂响应不同的输出(json/text/html)。
核⼼原理
简单画了下流程图,步骤如下:
初始化时会到实现了 GlobalHandelException 接⼝的类,将它实例化并注册到 IOC 容器中。当发⽣异
常时从容器中获取到异常处理器的对象,执⾏其中的处理函数即可。
说了半天原理来看看源码是如何实现的。
在初始化 bean 时,如果是⼀个异常处理器则会将他单独存放(也就相当于前⽂说的打标识)。其中的 GlobalHandelException 本⾝的定义也⾮常简单:
接下来是运⾏时:
⽽当出现异常时则会通过之前的保存的异常处理 bean 进⾏异常处理,在调⽤的同时将全局上下⽂及异常信息传递过去就齐活了。
这样就可以在这个实现类中实现我们⾃⼰的异常处理逻辑了。
总结
万⼀今后⾯试官问你们 SpringMVC 的异常处理是如何实现的?你该知道怎么回答了吧 。
同时也可以发散⼀下,是否可以配置⼀个针对于某⼀个 controller 的异常处理,这样每个 controller 产⽣
的异常可以单独处理,如果没有配置则进⼊全局异常;原理也差不多,感兴趣的朋友可以提个 PR 完成该 feature。
项⽬源码:
以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。