Spring (64)Spring框架如何处理异常

发布于:2024-06-19 ⋅ 阅读:(101) ⋅ 点赞:(0)

Spring框架提供了一个灵活的异常处理框架,允许开发者以一致的方式处理来自应用程序的异常。这个框架主要围绕以下几个关键概念构建:

  1. ExceptionResolver: 用于解析异常并映射到处理程序的组件。
  2. @ExceptionHandler: 用于标记一个方法来处理特定的异常。
  3. ControllerAdvice: 用于定义全局的异常处理逻辑。
  4. ResponseEntityExceptionHandler: 提供了基础的异常处理方法,可被扩展。

ExceptionResolver

HandlerExceptionResolver接口定义了异常处理的机制。Spring提供了多个实现:

  • SimpleMappingExceptionResolver
  • DefaultHandlerExceptionResolver
  • ResponseStatusExceptionResolver
  • ExceptionHandlerExceptionResolver (通常与@ExceptionHandler一起使用)

DispatcherServlet在处理请求过程中发现异常时,会委托给一系列的HandlerExceptionResolver实现来解析。

@ExceptionHandler

@ExceptionHandler注解允许你定义方法来处理特定的异常。当控制器抛出异常时,Spring会寻找匹配的@ExceptionHandler方法并调用它。

例如:

@Controller
public class MyController {

    @RequestMapping("/somePath")
    public String handleRequest() {
        // 模拟异常
        throw new CustomException("Error occurred");
    }

    @ExceptionHandler(CustomException.class)
    public ResponseEntity<String> handleException(CustomException e) {
        // 处理异常
        return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

ControllerAdvice

@ControllerAdvice是一个组件注解,允许你在一个地方定义全局的异常处理逻辑,而不是在每个控制器中重复定义。它可以与@ExceptionHandler一起使用。

例如:

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(CustomException.class)
    public ResponseEntity<String> handleCustomException(CustomException e) {
        // 全局异常处理逻辑
        return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleException(Exception e) {
        // 全局异常处理逻辑
        return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

ResponseEntityExceptionHandler

ResponseEntityExceptionHandler是一个便捷的基类,它提供了一些方法来处理常见的异常。你可以通过扩展这个类并添加@ExceptionHandler方法来提供自己的实现。

深入源码解析

当Spring的DispatcherServlet处理请求时,如果发生异常,它将通过一系列的HandlerExceptionResolver来尝试解析这个异常。

以下是简化版本的DispatcherServlet处理异常的流程:

public void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
    try {
        // ...处理请求...
    } catch (Exception ex) {
        processDispatchResult(request, response, null, ex);
    }
}

protected void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
        @Nullable ModelAndView mv, @Nullable Exception ex) throws Exception {

    if (ex != null) {
        for (HandlerExceptionResolver resolver : this.handlerExceptionResolvers) {
            ModelAndView resolved = resolver.resolveException(request, response, null, ex);
            if (resolved != null) {
                // 如果找到了一个解析器能处理这个异常,就使用它解析的ModelAndView
                render(resolved, request, response);
                return;
            }
        }
        // 如果没有解析器能处理这个异常,则抛出
        throw ex;
    }
}

其中,handlerExceptionResolvers是一个HandlerExceptionResolver的列表,Spring会按顺序尝试使用这些解析器来处理异常。如果找到合适的解析器,则会渲染相应的视图。如果没有,则会抛出原始异常。

每个HandlerExceptionResolver可以根据不同的需求进行配置和扩展,提供对异常处理的细粒度控制。通过组合HandlerExceptionResolver@ExceptionHandler,Spring提供了一种既强大又灵活的异常处理机制。