Spring框架提供了一个灵活的异常处理框架,允许开发者以一致的方式处理来自应用程序的异常。这个框架主要围绕以下几个关键概念构建:
- ExceptionResolver: 用于解析异常并映射到处理程序的组件。
- @ExceptionHandler: 用于标记一个方法来处理特定的异常。
- ControllerAdvice: 用于定义全局的异常处理逻辑。
- 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提供了一种既强大又灵活的异常处理机制。