在Java Web开发中,SpringMVC是构建Web应用的主流框架之一。相信许多开发者在使用过程中会有疑问:为什么没有编写传统Servlet,Controller却能处理请求?HandlerAdapter究竟有什么作用?本文将通过流程图、代码示例和生活化比喻,深入解析SpringMVC的核心原理与请求处理机制。
SpringMVC基于MVC(Model-View-Controller)模式,将Web应用分为三个核心部分:
其核心组件包括:
// DispatcherServlet的简化继承关系
public class DispatcherServlet extends FrameworkServlet {
// 处理HTTP请求的核心逻辑
}
@GetMapping("/users/{id}")
映射到对应处理方法@RestController
注解简化开发,自动返回JSON@RestController
@RequestMapping("/api")
public class UserController {
@GetMapping("/users/{id}")
public User getUser(@PathVariable Long id) {
return userService.getUserById(id);
}
}
可以理解这里的HandlerAdapter就是一个三孔排插,既能插两孔的插头也能插三孔的插头,但是这里的插座(DispatcherServlet)只支持三孔插头,而我们的一系列插头(Controller)里既有三孔又有两孔,需要HandlerAdapter来统一适配一下。这里HandlerMapping只是告诉你哪个插头(Controller)是DispatcherServlet想要的,但是真正要用的时候还得适配一下。
HandlerExecutionChain
是Spring MVC中负责封装请求处理器(Handler)及其相关拦截器(Interceptor)的核心组件,它在请求处理流程中扮演着"执行链条管理器"的角色。以下从多个维度详细解析其作用:
HandlerExecutionChain
主要包含两部分:
// HandlerExecutionChain简化结构
public class HandlerExecutionChain {
private final Object handler; // 处理器
private final List<HandlerInterceptor> interceptors; // 拦截器列表
// 前置处理:在Handler执行前调用
boolean applyPreHandle(HttpServletRequest request,
HttpServletResponse response) throws Exception { ... }
// 后置处理:在Handler执行后调用
void applyPostHandle(HttpServletRequest request,
HttpServletResponse response,
ModelAndView mv) throws Exception { ... }
// 完成后处理:在视图渲染完成后调用
void triggerAfterCompletion(HttpServletRequest request,
HttpServletResponse response,
Exception ex) throws Exception { ... }
}
public interface HandlerInterceptor {
// 预处理:在Handler执行前调用
default boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
return true; // 返回true继续执行链,返回false终止
}
// 后处理:在Handler执行后但视图渲染前调用
default void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
@Nullable ModelAndView modelAndView) throws Exception {
}
// 完成后处理:在视图渲染完成后调用
default void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
@Nullable Exception ex) throws Exception {
}
}
HandlerExecutionChain的核心作用
拦截器执行特点
preHandle
按注册顺序执行,任何一个返回false
则终止请求postHandle
按注册逆序执行afterCompletion
按注册逆序执行,无论请求是否成功与过滤器(Filter)的区别
SpringMVC支持多种处理器类型:
@RestController
)由于这些处理器的方法签名和调用方式不同,需要HandlerAdapter
作为中间层进行适配。
// DispatcherServlet中的关键调用逻辑
HandlerExecutionChain chain = getHandler(request);
HandlerAdapter ha = getHandlerAdapter(chain.getHandler());
// 通过适配器调用处理器
ModelAndView mv = ha.handle(request, response, chain.getHandler());
Spring Boot通过@SpringBootApplication
自动配置DispatcherServlet:
@Configuration
public class WebMvcAutoConfiguration {
@Bean
public DispatcherServlet dispatcherServlet() {
return new DispatcherServlet();
}
@Bean
public ServletRegistrationBean<DispatcherServlet> dispatcherServletRegistration() {
return new ServletRegistrationBean<>(dispatcherServlet(), "/");
}
}
@RestController
@RequestMapping("/api")
public class UserController {
// 映射GET /api/users/{id}
@GetMapping("/users/{id}")
public User getUser(@PathVariable Long id) { ... }
// 映射POST /api/users
@PostMapping("/users")
public User createUser(@RequestBody User user) { ... }
}
SpringMVC支持JSP、Thymeleaf、FreeMarker等视图技术:
@Controller
public class ViewController {
@GetMapping("/home")
public String home(Model model) {
model.addAttribute("message", "Hello SpringMVC");
return "home"; // 视图名称,由ViewResolver解析
}
}
@RestController
等注解简化开发@RestController
和@RequestMapping
@ControllerAdvice
统一处理异常通过深入理解SpringMVC的核心原理和请求处理机制,开发者可以更高效地构建Web应用,同时在遇到问题时能够快速定位和解决。