96SEO 2026-02-19 19:01 13
www.bilibili.com/video/BV1sS411c7Mo

二、全局异常拦截点2-1、入口2-2、全局异常拦截器是如何注入到
四、其它4-1、设置HTTP状态码4-2、异常处理器排序4-3、所谓全局异常
最近在做系统升级的时候引发了一个BUG原本系统是有一个异常处理器A引入了某个底包中也带了一个异常处理器B最终走了底包的异常处理器B。
A对于异常的时候会返回HTTP状态码为500B对于异常处理器返回的HTTP状态码为200前端基于HTTP状态码进行提示的就出了问题
本篇文章我们就来讨论一下在JavaWeb中的全局异常处理器是何时何地如何执行的。
在进行学习之前需要先知道HTTP执行流程SpringMVC执行流程
HandlerExceptionResolver简单来说就是实现或间接实现它的类就叫全局异常处理器。
org.springframework.web.servlet;import
javax.servlet.http.HttpServletRequest;
javax.servlet.http.HttpServletResponse;
org.springframework.lang.Nullable;public
resolveException(HttpServletRequest
SpringBoot项目最大的特点就是注解在SpringBoot项目中全局异常拦截的注解是ControllerAdvice
ExceptionHandlerExceptionResolver
doResolveHandlerMethodException
AbstractHandlerMethodExceptionResolver
LoggerFactory.getLogger(ExceptionHandler.class);Overrideprotected
doResolveHandlerMethodException(HttpServletRequest
org.springframework.web.servlet.DispatcherServlet#doDispatch
这个方法就是SpringMVC的执行流程的核心代码了下面是简化代码
WebAsyncUtils.getAsyncManager(request);try
异常处理的入口processDispatchResult(processedRequest,
}org.springframework.web.servlet.DispatcherServlet#processDispatchResult
processDispatchResult(HttpServletRequest
processHandlerException(request,
}org.springframework.web.servlet.DispatcherServlet#processHandlerException
processHandlerException(HttpServletRequest
typesrequest.removeAttribute(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE);//
HandlerExceptionResolvers...ModelAndView
(this.handlerExceptionResolvers
this.handlerExceptionResolvers)
resolver.resolveException(request,
handlerExceptionResolvers;在DispatcherServlet里面有一个onRefresh方法它是重写的父类FrameworkServlet的在初始化ServletBean的时候会被调用一次它里面会做很多初始化的操作其中一个就是获取容器里面的全局异常拦截器
initStrategies(ApplicationContext
...initHandlerExceptionResolvers(context);//
initHandlerExceptionResolvers(ApplicationContext
{this.handlerExceptionResolvers
(this.detectAllHandlerExceptionResolvers)
HandlerExceptionResolverMapString,
BeanFactoryUtils.beansOfTypeIncludingAncestors(context,
HandlerExceptionResolver.class,
{this.handlerExceptionResolvers
ArrayList(matchingBeans.values());//
排序AnnotationAwareOrderComparator.sort(this.handlerExceptionResolvers);}}//
ExceptionHandlerExceptionResolver
org.springframework.web.servlet.mvc.method.annotation;public
ExceptionHandlerExceptionResolver
AbstractHandlerMethodExceptionResolverimplements
}⚠️可以回到【全局异常处理器的类型】的图看看ExceptionHandlerExceptionResolver其实就是全局异常处理器HandlerExceptionResolver的子类
InitializingBean重写了afterPropertiesSet这个方法会在bean初始化完之后执行
beansinitExceptionHandlerAdviceCache();//
}initExceptionHandlerAdviceCache
initExceptionHandlerAdviceCache()
ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());for
IllegalStateException(Unresolvable
注解ExceptionHandlerMethodResolver
ExceptionHandlerMethodResolver(beanType);if
(resolver.hasExceptionMappings())
存入当前的类参数里面this.exceptionHandlerAdviceCache.put(adviceBean,
(ResponseBodyAdvice.class.isAssignableFrom(beanType))
{this.responseBodyAdvice.add(adviceBean);}}//
}org.springframework.web.method.ControllerAdviceBean#findAnnotatedBeans
findAnnotatedBeans(ApplicationContext
ConfigurableApplicationContext)
((ConfigurableApplicationContext)
context).getBeanFactory();}ListControllerAdviceBean
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory,
(!ScopedProxyUtils.isScopedTarget(name))
beanFactory.findAnnotationOnBean(name,
排序OrderComparator.sort(adviceBeans);return
中org.springframework.web.method.annotation.ExceptionHandlerMethodResolver#ExceptionHandlerMethodResolver
ExceptionHandlerMethodResolver(Class?
MethodIntrospector.selectMethods(handlerType,
detectExceptionMappings(method))
{addExceptionMapping(exceptionType,
this.mappedMethods.put(exceptionType,
IllegalStateException(Ambiguous
生成了一个ExceptionHandlerExceptionResolver它通过多级实现了
HandlerExceptionResolver所有使用ControllerAdvice的类都存在了
HandlerExceptionResolver.resolveException方法它只有这一个方法从【3-1】得知所有使用
注解的类都被存在了ExceptionHandlerExceptionResolver
中从【1】得知ExceptionHandlerExceptionResolver的继承关系如下图
这个很简单直接去看即可org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#doResolveHandlerMethodException
执行过程就是循环exceptionHandlerAdviceCache中的每一个全局拦截器再循环每个拦截器里面的mappedMethods看哪个可以匹配上就执行哪个
大多数情况下我们会自定义返回值code比如未鉴权返回给前端HTTP状态码是200code为401但在某些情况下也会直接返回HTTP状态码401可以使用
ResponseStatus(HttpStatus.UNAUTHORIZED)
ExceptionHandler(Exception.class)
并不是系统任何异常都会被它所拦截因为我们已经知道它的执行点是在MVC的流程中所以就只有HTTP异常才会被拦截处理
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback