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

相关文章

  • SpringBoot 实现动态添加定时任务功能

    SpringBoot 实现动态添加定时任务功能

    这篇文章主要介绍了SpringBoot 动态添加定时任务,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-02-02
  • SpringBoot集成kafka全面实战记录

    SpringBoot集成kafka全面实战记录

    在实际开发中,我们可能有这样的需求,应用A从TopicA获取到消息,经过处理后转发到TopicB,再由应用B监听处理消息,即一个应用处理完成后将该消息转发至其他应用,完成消息的转发,这篇文章主要介绍了SpringBoot集成kafka全面实战,需要的朋友可以参考下
    2021-11-11
  • Java实现PDF转为线性PDF详解

    Java实现PDF转为线性PDF详解

    线性化PDF文件是PDF文件的一种特殊格式,可以通过Internet更快地进行查看。本文将通过后端Java程序实现将PDF文件转为线性化PDF。感兴趣的可以了解一下
    2021-12-12
  • SpringBoot使用MockMvc测试get和post接口的示例代码

    SpringBoot使用MockMvc测试get和post接口的示例代码

    Spring Boot MockMvc是一个用于单元测试的模块,它是Spring框架的一部分,专注于简化Web应用程序的测试,MockMvc主要用来模拟一个完整的HTTP请求-响应生命周期,本文给大家介绍了SpringBoot使用MockMvc测试get和post接口,需要的朋友可以参考下
    2024-06-06
  • Spring Cloud Alibaba和Dubbo融合实现

    Spring Cloud Alibaba和Dubbo融合实现

    这篇文章主要介绍了Spring Cloud Alibaba和Dubbo融合实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • 一文带你搞懂SpringBoot中自动装配原理

    一文带你搞懂SpringBoot中自动装配原理

    这篇文章主要为大家详细介绍了SpringBoot中自动装配原理的相关知识,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考下
    2025-01-01
  • Spring自带的校验框架Validation的使用实例

    Spring自带的校验框架Validation的使用实例

    今天小编就为大家分享一篇关于Spring自带的校验框架Validation的使用实例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03
  • Java SpringBoot整合shiro-spring-boot-starterqi项目报错解决

    Java SpringBoot整合shiro-spring-boot-starterqi项目报错解决

    这篇文章主要介绍了Java SpringBoot整合shiro-spring-boot-starterqi项目报错解决,文章围绕主题展开详细的内容介绍,具有一定的参考一下
    2022-08-08
  • JAVA 对象创建与对象克隆

    JAVA 对象创建与对象克隆

    这篇文章主要介绍了JAVA 对象创建与对象克隆,new 创建、反射、克隆、反序列化,克隆它分为深拷贝和浅拷贝,通过调用对象的 clone方法,进行对象的克隆,下面来看看文章的详细内容吧
    2022-02-02
  • 利用Spring AOP记录方法的执行时间

    利用Spring AOP记录方法的执行时间

    这篇文章给大家介绍的是spring的aop来实现方法级的执行时间的记录监控,以此来评估方法的性能以及针对性的对已存在的方法进行优化。对于监控,我们比较关注监控的可靠性和性能,准确,高效,这才能在不影响整体性能的情况下对我们的系统性能有个较准确的认识。
    2016-09-09

最新评论