简述 Spring MVC 的核心组件及其处理请求的大致流程。
·
Spring MVC 核心组件
1. DispatcherServlet(前端控制器)
- Spring MVC 的核心入口
- 负责接收所有 HTTP 请求并分发到相应的处理器
- 继承自
HttpServlet,是整个流程的调度中心
2. HandlerMapping(处理器映射器)
- 根据请求 URL 找到对应的 Controller 方法
- 常用实现:
RequestMappingHandlerMapping - 维护 URL 与处理器的映射关系
3. Controller(处理器)
- 处理具体业务逻辑的组件
- 使用
@Controller或@RestController注解标识 - 返回逻辑视图名或数据
4. HandlerAdapter(处理器适配器)
- 调用 Controller 方法
- 解析方法参数、处理返回值
- 常用实现:
RequestMappingHandlerAdapter
5. ViewResolver(视图解析器)
- 将逻辑视图名解析为物理视图资源
- 常用实现:
InternalResourceViewResolver - 支持 JSP、Thymeleaf、FreeMarker 等
6. View(视图)
- 负责渲染数据并生成响应
- 可以是 JSP、HTML、JSON 等
7. HandlerInterceptor(拦截器)
- 在请求处理前后进行拦截
- 类似 Filter,但更专注于 MVC 层
- 可用于权限校验、日志记录等
8. ModelAndView
- 封装模型数据和视图信息
- Controller 可以返回此对象
Spring MVC 请求处理流程
┌─────────────────────────────────────────────────────────────────────┐
│ 请求处理流程 │
└─────────────────────────────────────────────────────────────────────┘
① 用户发送 HTTP 请求
│
▼
② DispatcherServlet 接收请求
│
▼
③ HandlerInterceptor.preHandle() 【拦截器前置处理】
│
▼
④ HandlerMapping 查找对应的 Controller 方法
│
▼
⑤ HandlerAdapter 调用 Controller 方法
│
▼
⑥ Controller 执行业务逻辑,返回 ModelAndView 或数据
│
▼
⑦ HandlerInterceptor.postHandle() 【拦截器后置处理】
│
▼
⑧ ViewResolver 解析视图名(如果是视图)
│
▼
⑨ View 渲染数据,生成响应
│
▼
⑩ HandlerInterceptor.afterCompletion() 【拦截器完成后处理】
│
▼
⑪ DispatcherServlet 返回响应给用户
详细流程说明
步骤 1:请求到达
浏览器 → HTTP 请求 → DispatcherServlet
步骤 2:DispatcherServlet 分发
// DispatcherServlet 核心方法
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) {
// 1. 获取处理器执行链
HandlerExecutionChain mappedHandler = getHandler(request);
// 2. 获取处理器适配器
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// 3. 执行拦截器 preHandle
if (!mappedHandler.applyPreHandle(request, response)) {
return;
}
// 4. 调用 Controller 方法
ModelAndView mv = ha.handle(request, response, mappedHandler.getHandler());
// 5. 执行拦截器 postHandle
mappedHandler.applyPostHandle(request, response, mv);
// 6. 渲染视图
processDispatchResult(request, response, mappedHandler, mv);
}
步骤 3:HandlerMapping 查找处理器
// 根据 URL 查找对应的 Controller 方法
GET /users → UserController.findAll()
POST /users → UserController.create()
GET /users/{id} → UserController.findById(id)
步骤 4:HandlerAdapter 执行处理器
// 解析参数、调用方法、处理返回值
@RequestMapping("/users")
public List<User> findAll() {
return userService.findAll();
}
步骤 5:视图解析与渲染
// 逻辑视图名 → 物理视图
"users" → "/WEB-INF/views/users.jsp"
核心组件配置示例
传统 XML 配置
<!-- web.xml -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- spring-mvc.xml -->
<context:component-scan base-package="com.example.controller"/>
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
Java 配置
@Configuration
@EnableWebMvc
@ComponentScan("com.example.controller")
public class WebConfig implements WebMvcConfigurer {
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/login", "/register");
}
}
// 初始化类
public class WebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{RootConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{WebConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
拦截器示例
@Component
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
// 请求处理前
HttpSession session = request.getSession();
if (session.getAttribute("user") == null) {
response.sendRedirect("/login");
return false; // 阻止继续执行
}
return true;
}
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView) throws Exception {
// 请求处理后,视图渲染前
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex) throws Exception {
// 请求完成后,视图渲染后
}
}
流程总结图
┌──────────────┐
│ 浏览器 │
└──────┬───────┘
│ HTTP 请求
▼
┌─────────────────────────────────────────────────────────┐
│ DispatcherServlet │
│ ┌─────────────────────────────────────────────────┐ │
│ │ 1. HandlerMapping → 找到 Controller │ │
│ │ 2. HandlerAdapter → 调用 Controller 方法 │ │
│ │ 3. ViewResolver → 解析视图 │ │
│ │ 4. View → 渲染响应 │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
│
▼
┌──────────────┐
│ 浏览器 │
└──────────────┘
关键点总结
| 组件 | 职责 |
|---|---|
| DispatcherServlet | 中央调度器,统一入口 |
| HandlerMapping | URL → Controller 映射 |
| HandlerAdapter | 调用 Controller 方法 |
| Controller | 业务逻辑处理 |
| ViewResolver | 视图名 → 视图资源 |
| View | 渲染响应 |
| Interceptor | 横切逻辑处理 |
更多推荐

所有评论(0)