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注解原理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 使用SpringMVC返回json字符串的实例讲解

    使用SpringMVC返回json字符串的实例讲解

    下面小编就为大家分享一篇使用SpringMVC返回json字符串的实例讲解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-03-03
  • java 遍历Map的几种方法总结

    java 遍历Map的几种方法总结

    这篇文章主要介绍了java 遍历Map的四种方法,帮助大家更好的理解和学习Java,感兴趣的朋友可以了解下
    2020-10-10
  • Java去掉小数点后面无效0的方案与建议

    Java去掉小数点后面无效0的方案与建议

    当前小数点后面的位数过多的时候,多余的0没有实际意义,下面这篇文章主要给大家介绍了关于Java去掉小数点后面无效0的方案与建议,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2022-07-07
  • Java验证码功能的实现方法

    Java验证码功能的实现方法

    这篇文章主要为大家详细介绍了Java验证码功能的实现方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-11-11
  • 详解Java中String类的各种用法

    详解Java中String类的各种用法

    Java中定义了String和StringBuffer两个类来封装对字符串的各种操作,存放于java.lang包中,是Java语言的核心类,提供了字符串的比较、查找、截取、大小写转换等操作,无需导入即可直接使用它们。让我们来详细了解它吧
    2021-11-11
  • Java如何判断字符串中是否包含某个字符

    Java如何判断字符串中是否包含某个字符

    这篇文章主要介绍了Java如何判断字符串中是否包含某个字符,可以使用String类的contains()方法,另一种方法使用String类的indexOf方法,本文结合示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-02-02
  • Spring Boot 基于 SCRAM 认证集成 Kafka 的过程详解

    Spring Boot 基于 SCRAM 认证集成 Kafka 的过程详解

    在本篇文章中,我们将探讨如何在 Spring Boot 应用中集成 Kafka 并使用 SCRAM 认证机制进行安全连接,并实现动态创建账号、ACL 权限、Topic,以及生产者和消费者等操作,感兴趣的朋友跟随小编一起看看吧
    2024-08-08
  • 通过jstack分析解决进程死锁问题实例代码

    通过jstack分析解决进程死锁问题实例代码

    这篇文章主要介绍了通过jstack分析解决进程死锁问题实例代码,具有一定借鉴价值,需要的朋友可以参考下
    2018-01-01
  • Java面向对象全解析之this关键字+构造方法+标准JavaBean

    Java面向对象全解析之this关键字+构造方法+标准JavaBean

    本文介绍了Java面向对象的高级内容,包括无参构造方法和带参构造方法,标准JavaBean类是企业开发中用于封装数据的规范类,必须遵循特定的命名和方法规范,通过本文学习,读者可以掌握这些关键概念并应用到实际开发中,感兴趣的朋友跟随小编一起看看吧
    2026-01-01
  • java GUI编程之paint绘制操作示例

    java GUI编程之paint绘制操作示例

    这篇文章主要介绍了java GUI编程之paint绘制操作,结合实例形式详细分析了java GUI编程paint绘制相关操作技巧与使用注意事项,需要的朋友可以参考下
    2020-01-01

最新评论