暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

得物1面:Spring @ExceptionHandler注解的工作原理是什么?

猿java 2025-03-21
44

你好,我是猿java

点击关注公众号👇,获取:大厂简历指导和加技术群深度讨论!

在日常工作中,我们通常会是使用 @ExceptionHandler
注解来处理控制器(Controller)层面的异常,从而提高代码的可维护性和复用性。那么,@ExceptionHandler
注解是如何工作的?我们需要注意什么?这篇文章,我们来看一道得物的面试题。

1. 主要作用

首先,我们来看看@ExceptionHandler
注解的源码,截图如下:

通过源码,我们可以看到@ExceptionHandler
注解只能用于方法上。从整体上看,@ExceptionHandler
注解的作用主要有下面两点:

  • 局部异常处理:在单个控制器类中使用@ExceptionHandler
    ,只对该控制器内部的方法抛出的异常进行处理。这种方式适用于特定控制器需要独立处理某些异常的场景。

  • 全局异常处理:结合@ControllerAdvice
    注解,可以定义全局的异常处理逻辑,适用于整个应用程序中所有控制器抛出的异常。这种方式有助于统一的异常处理机制,避免在每个控制器中重复编写异常处理代码。

使用@ExceptionHandler
注解的好处有下面几点:

  • 代码简洁:将异常处理逻辑与业务逻辑分离,避免在每个控制器方法中重复编写异常处理代码。
  • 可维护性强:集中管理异常处理逻辑,便于修改和扩展。
  • 灵活性高:支持局部和全局的异常处理,满足不同场景下的需求。

2. 原理

@ExceptionHandler
的实现基于Spring的异常处理机制,主要涉及以下几个关键组件:

  • 异常解析器(HandlerExceptionResolver):Spring MVC使用HandlerExceptionResolver
    接口来解析控制器方法抛出的异常。@ExceptionHandler
    是通过这种解析机制实现的。

  • 反射机制:当控制器方法抛出异常时,Spring会扫描该控制器类中带有@ExceptionHandler
    注解的方法,匹配异常类型,找到合适的异常处理方法。

  • 匹配策略

    1. 局部优先:首先查找当前控制器内带有@ExceptionHandler
      注解的方法,匹配异常类型,执行相应的处理逻辑。
    2. 全局处理:如果当前控制器没有匹配的@ExceptionHandler
      方法,则会查找使用@ControllerAdvice
      注解的类中定义的全局异常处理方法。
    3. 默认处理:如果没有找到任何匹配的异常处理方法,Spring会使用其默认的异常处理机制,通常会返回一个错误页面或错误响应。

3. 使用方法

在控制器类中定义带有@ExceptionHandler
注解的方法,示例如下:

@Controller
publicclass TestController {

    @RequestMapping("/tes")
    public String example() {
        // 可能抛出异常的业务逻辑
        if (someCondition) {
            thrownew CustomException("自定义异常发生");
        }
        return"success";
    }

    @ExceptionHandler(CustomException.class)
    public ModelAndView handleCustomException(CustomException ex
{
        ModelAndView mav = new ModelAndView("errorView");
        mav.addObject("message", ex.getMessage());
        return mav;
    }
}

在上述示例中,当/test
请求处理方法抛出CustomException
时,handleCustomException
方法会被调用,返回一个指向errorView
视图的ModelAndView
对象,并将异常信息传递给视图。

另外,我们可以通过结合@ControllerAdvice
@ExceptionHandler
两个注解,可以实现全局异常处理,示例如下:

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public ModelAndView handleAllExceptions(Exception ex
{
        ModelAndView mav = new ModelAndView("globalErrorView");
        mav.addObject("message", ex.getMessage());
        return mav;
    }
}

这样,无论哪个控制器抛出Exception
或其子类异常,handleAllExceptions
方法都会处理这些异常,从而实现统一的异常处理逻辑。

4. 注意事项

尽管@ExceptionHandler
注解在Spring中提供了一种优雅而高效的方式来处理应用中的异常,但是在使用的过程中,我们也需要注意以下几点:

  • @ExceptionHandler
    方法的返回值可以是ModelAndView
    ResponseEntity
    ,或直接返回视图名称,具体取决于应用的需求。
  • 异常处理方法可以接收异常对象作为参数,也可以接收其他与请求相关的参数,如HttpServletRequest
    HttpServletResponse
    等。
  • 在使用全局异常处理时,应合理定义异常层次结构和处理策略,以确保不同类型的异常得到正确的处理。

5. 总结

本文,我们分析了@ExceptionHandler
注解的使用方法,了解了@ExceptionHandler
注解在Spring中的作用,以及它的优势和注意事项。在实际工作中,我们可以使用@ExceptionHandler
注解更优雅地处理异常。

文章总结不易,求一键三连:点赞、转发、在看另外,为了方便大家更深入地进行技术交流,我维护了一个猿java内部的技术交流群,欢迎大家加群讨论。关注公众号「猿java」,回复「加群」即可。

文章转载自猿java,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论