SpringBoot中的@ControllerAdvice注解原理详解

 更新时间:2024年01月16日 08:33:30   作者:加油当当  
这篇文章主要介绍了SpringBoot中的@ControllerAdvice注解原理详解,在SpringBoot应用程序启动过程中,Spring会扫描所有的类,寻找带有@ControllerAdvice注解的类这些方法会被添加到一个映射表中,以便后续处理异常时能找到对应的处理方法,需要的朋友可以参考下

@ControllerAdvice注解原理

1. 启动时扫描 @ControllerAdvice 注解

在 Spring Boot 应用程序启动过程中,Spring 会扫描所有的类,寻找带有 @ControllerAdvice 注解的类。

这是通过 ConfigurationClassPostProcessor 和 ComponentScanAnnotationParser 来完成的。

这些类会被实例化并作为 Spring Bean 注入到 Spring 容器中。

2. ControllerAdviceBeanPostProcessor

ControllerAdviceBeanPostProcessor 是一个实现了 BeanPostProcessor 接口的类。

在应用程序启动过程中,所有 Bean 初始化之后,ControllerAdviceBeanPostProcessor 的 postProcessAfterInitialization 方法会被调用。

该方法负责处理带有 @ControllerAdvice 注解的类;

postProcessAfterInitialization:

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    if (bean instanceof ControllerAdviceBean) {
        ControllerAdviceBean adviceBean = (ControllerAdviceBean) bean;
        Class<?> beanType = adviceBean.getBeanType();
        if (beanType != null) {
            ExceptionHandlerMethodResolver resolver = new ExceptionHandlerMethodResolver(beanType);
            if (resolver.hasExceptionMappings()) {
                this.exceptionHandlerAdviceCache.put(adviceBean, resolver);
            }
        }
    }
    return bean;
}

3. ExceptionHandlerMethodResolver

在上述 ControllerAdviceBeanPostProcessor 的方法中,会创建 ExceptionHandlerMethodResolver 实例来扫描带有 @ControllerAdvice 注解的类中的所有方法,找到使用了 @ExceptionHandler 注解的异常处理方法。这些方法会被添加到一个映射表中,以便后续处理异常时能找到对应的处理方法。

4. 注册异常处理方法

在 ControllerAdviceBeanPostProcessor 中,异常处理方法会被注册到一个全局的异常处理器映射表(exceptionHandlerAdviceCache)中。

映射表将异常类型与相应的处理方法关联起来,以便在发生异常时能够找到正确的处理方法。

5. 请求处理和异常捕获

当 Spring Boot 应用程序接收到一个请求时,它会将请求分派给相应的 Controller 方法。

在执行 Controller 方法时,如果抛出了异常,DispatcherServlet 会将异常传递给 HandlerExceptionResolver 来处理。

在这里,ExceptionHandlerExceptionResolver 会被调用。

6. ExceptionHandlerExceptionResolver

ExceptionHandlerExceptionResolver 类负责在全局异常处理器映射表(exceptionHandlerAdviceCache)中查找与异常类型关联的处理方法,并执行这个方法来处理异常。

具体实现在 doResolveHandlerMethodException 方法中:

protected ModelAndView doResolveHandlerMethodException(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod, Exception exception) {
    // ...
    ServletInvocableHandlerMethod exceptionHandlerMethod = getExceptionHandlerMethod(handlerMethod, exception);
    if (exceptionHandlerMethod == null) {
       return null;
   }
   // ...
   try {
       exceptionHandlerMethod.invokeAndHandle(webRequest, mavContainer, exceptionResult);
   } catch (Exception invocationEx) {
       // ...
   }
   // ...
   return ModelAndViewResolver.UNRESOLVED;
}

在这个方法中,`ExceptionHandlerExceptionResolver` 会根据异常类型查找对应的处理方法。

如果找到了适合的处理方法,它将使用 `ServletInvocableHandlerMethod` 类的实例来执行该方法,并将异常处理结果(通常是一个 ModelAndView 对象或 ResponseEntity 对象)返回给客户端;

总结

`@ControllerAdvice` 的工作原理在 Spring Boot 应用程序启动时涉及到多个组件和步骤;

在启动过程中,`ControllerAdviceBeanPostProcessor` 会扫描带有 `@ControllerAdvice` 注解的类,`ExceptionHandlerMethodResolver` 会扫描这些类中的异常处理方法并将它们注册到全局异常处理器映射表中。当请求处理过程中发生异常时,`ExceptionHandlerExceptionResolver` 会从映射表中查找并执行相应的异常处理方法;

到此这篇关于SpringBoot中的@ControllerAdvice注解原理详解的文章就介绍到这了,更多相关@ControllerAdvice注解原理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 使用Spring自身提供的地址匹配工具匹配URL操作

    使用Spring自身提供的地址匹配工具匹配URL操作

    这篇文章主要介绍了使用Spring自身提供的地址匹配工具匹配URL操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • spring webflux响应式编程使用详解

    spring webflux响应式编程使用详解

    webflux,即响应式编程,响应式编程是一种用于处理异步数据流和事件的编程范式,spring webflux是spring在5.0版本后提供的一套响应式编程风格的web开发框架,本文给大家详细讲讲spring webflux响应式编程的使用,需要的朋友可以参考下
    2023-10-10
  • 深入聊一聊springboot项目全局异常处理那些事儿

    深入聊一聊springboot项目全局异常处理那些事儿

    最近在做项目时需要对异常进行全局统一处理,所以下面这篇文章主要给大家介绍了关于springboot项目全局异常处理那些事儿,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-01-01
  • JAVA中阻止类的继承(官方和非官方)

    JAVA中阻止类的继承(官方和非官方)

    在面向对象的理论中, 有一些方案要求你用一个办法来声明一个不可继承的类。一般而言,如果类提供的功能不应该被改变,或者更恰当的说,是被覆盖(override)的时候才会出现这种情况。在这篇文章里,我讨论在JAVA语言中的实现办法--官方和非官方的办法
    2014-01-01
  • java基础的详细了解第六天

    java基础的详细了解第六天

    这篇文章对Java编程语言的基础知识作了一个较为全面的汇总,在这里给大家分享一下。需要的朋友可以参考,希望能给你带来帮助
    2021-08-08
  • JAVA代码实现MongoDB动态条件之分页查询

    JAVA代码实现MongoDB动态条件之分页查询

    这篇文章主要介绍了JAVA如何实现MongoDB动态条件之分页查询,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-07-07
  • java ThreadPoolExecutor线程池内部处理流程解析

    java ThreadPoolExecutor线程池内部处理流程解析

    这篇文章主要为大家介绍了java ThreadPoolExecutor线程池内部处理流程解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • 基于JDK8-lambda表达式四种forEach性能对比

    基于JDK8-lambda表达式四种forEach性能对比

    这篇文章主要介绍了基于JDK8-lambda表达式四种forEach性能对比,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • 基于Java随机生成手机短信验证码的实例代码

    基于Java随机生成手机短信验证码的实例代码

    这篇文章主要介绍了Java随机生成手机短信验证码的实例代码,代码分为哦简单版和复杂版,需要的朋友可以参考下
    2019-04-04
  • uploadify java实现多文件上传和预览

    uploadify java实现多文件上传和预览

    这篇文章主要为大家详细介绍了java结合uploadify实现多文件上传和预览的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-10-10

最新评论