当调用一个controller时,spring做了哪些工作?
Spring 和 Tomcat 处理请求的源码分析涉及多个层次,包括 Tomcat 的请求接收和分发、Spring 的 DispatcherServlet 处理流程等。以下是详细的源码级别解析:
1. Tomcat 接收和分发请求
1.1 Tomcat 的 Connector 和 Processor
- Tomcat 的
Connector监听指定的端口(例如 8080)并接收 HTTP 请求。核心类是:org.apache.coyote.http11.Http11Processor- 它通过
process方法解析 HTTP 请求,将其转化为Request对象。
1.2 Servlet 容器调用
- Tomcat 的
StandardWrapperValve将请求交给注册的Servlet。- 代码路径:
public final void invoke(Request request, Response response) { // 找到对应的 Servlet 并调用其 service 方法 servlet.service(request, response); }
- 代码路径:
- 如果是 Spring Boot 项目,
DispatcherServlet会被注册为主处理 Servlet。
2. DispatcherServlet 的处理流程
2.1 DispatcherServlet 的核心逻辑
DispatcherServlet 是一个扩展自 HttpServlet 的类,其核心方法是 doDispatch。代码路径:
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HandlerExecutionChain mappedHandler = null;
try {
// 1. 根据请求查找对应的处理器(控制器)
mappedHandler = getHandler(request);
if (mappedHandler == null) {
noHandlerFound(request, response);
return;
}
// 2. 获取适配器(HandlerAdapter)调用控制器
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// 3. 执行前置拦截器
if (!mappedHandler.applyPreHandle(request, response)) {
return;
}
// 4. 调用控制器的方法并获取返回值
ModelAndView mv = ha.handle(request, response, mappedHandler.getHandler());
// 5. 渲染视图或直接返回数据
processDispatchResult(request, response, mappedHandler, mv);
} finally {
// 6. 执行后置拦截器
if (mappedHandler != null) {
mappedHandler.triggerAfterCompletion(request, response, null);
}
}
}
3. 核心组件源码解析
3.1 HandlerMapping
HandlerMapping 用于根据请求路径找到对应的处理器(控制器)。示例:
- 默认实现是
RequestMappingHandlerMapping,其核心方法:public HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception { String lookupPath = getUrlPathHelper().getLookupPathForRequest(request); return lookupHandlerMethod(lookupPath, request); }
3.2 HandlerAdapter
HandlerAdapter 用于调用控制器。常用实现是 RequestMappingHandlerAdapter,其核心方法:
@Override
@Nullable
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HandlerMethod handlerMethod = (HandlerMethod) handler;
// 1. 解析方法参数
Object[] args = getMethodArgumentValues(request, response, handlerMethod);
// 2. 调用控制器方法
Object returnValue = invokeHandlerMethod(handlerMethod, args);
// 3. 处理返回值
return getModelAndView(returnValue, handlerMethod);
}
3.3 HttpMessageConverter
- 如果控制器返回的是数据(如 JSON),Spring 使用
HttpMessageConverter序列化为响应体。 - 核心方法:
public void write(T t, MediaType contentType, HttpOutputMessage outputMessage) throws IOException { ObjectMapper mapper = ...; // 使用 Jackson 处理 JSON mapper.writeValue(outputMessage.getBody(), t); }
3.4 ViewResolver
- 如果控制器返回视图名称,Spring 使用
ViewResolver查找具体的视图实现。 - 核心方法:
@Nullable public View resolveViewName(String viewName, Locale locale) throws Exception { return this.viewResolvers.get(viewName); }
4. 流程总结
- Tomcat 接收请求
- 通过
Http11Processor解析请求并调用 Spring 的DispatcherServlet。
- 通过
- DispatcherServlet 分发请求
- 使用
HandlerMapping查找控制器。 - 使用
HandlerAdapter调用控制器方法。
- 使用
- 控制器处理逻辑
- Spring 解析参数,调用业务逻辑,并返回结果。
- 处理返回值
- 数据返回:通过
HttpMessageConverter序列化为 JSON。 - 视图返回:通过
ViewResolver渲染页面。
- 数据返回:通过
- Tomcat 返回响应
HttpServletResponse的内容被写入,并通过网络发送给客户端。
关键源码位置
-
Tomcat
org.apache.coyote.http11.Http11Processororg.apache.catalina.core.StandardWrapperValve
-
Spring
org.springframework.web.servlet.DispatcherServletorg.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapterorg.springframework.web.servlet.view.ViewResolverorg.springframework.http.converter.HttpMessageConverter
通过上述源码分析,Spring 和 Tomcat 协同完成了请求接收、分发、处理、到响应的完整流程。

浙公网安备 33010602011771号