错误场景
验证请求的Token合法性的Filter。Token校验失败时,直接抛自定义异常,移交给Spring处理:
测试HTTP请求:
日志输出如下:说明IllegalRequestExceptionHandler未生效。
why?
这就需要精通Spring异常处理流程了。
解析
当所有Filter被执行完毕,Spring才会处理Servlet相关,而DispatcherServlet才是整个Servlet处理核心,它是前端控制器设计模式,提供 Spring Web MVC 的集中访问点并负责职责的分派。
在这,Spring处理了请求和处理器的对应关系及统一异常处理。
Filter内异常无法被统一处理,就是因为异常处理发生在 DispatcherServlet#doDispatch()
但此时,过滤器已全部执行完。
Spring异常统一处理
ControllerAdvice如何被Spring加载并对外暴露?
WebMvcConfigurationSupport#handlerExceptionResolver()
实例化并注册一个ExceptionHandlerExceptionResolver 的实例
最终按下图调用栈,Spring 实例化了ExceptionHandlerExceptionResolver类。
ExceptionHandlerExceptionResolver实现了InitializingBean
重写 afterPropertiesSet()
initExceptionHandlerAdviceCache
完成所有 ControllerAdvice 中的ExceptionHandler 初始化:查找所有 @ControllerAdvice 注解的 Bean,把它们放入exceptionHandlerAdviceCache。
这里即指自定义的IllegalRequestExceptionHandler
所有被 @ControllerAdvice 注解的异常处理器,都会在 ExceptionHandlerExceptionResolver 实例化时自动扫描并装载在其exceptionHandlerAdviceCache。