Spring Boot 处理 HTTP 请求流程

发布于:2024-05-07 ⋅ 阅读:(25) ⋅ 点赞:(0)

Spring Boot 处理 HTTP 请求流程

Step 1: 请求到达服务器

当用户发送一个HTTP请求,这个请求首先会到达Spring Boot应用的端口,被服务器(例如Tomcat)接收。

Step 2: Servlet容器处理请求

接收到请求后,Tomcat Servlet容器会解析HTTP请求,把请求包装为HttpServletRequest对象。这个过程是在Tomcat的内部实现的,遵循Servlet规范,不涉及到Spring Boot的具体代码。它们的处理过程主要是由Connector组件负责的。主要通过以下几个步骤来完成:

  1. 接收请求: 这一切都从 org.apache.coyote 包下的 abtractProtocol类开始。接收请求是通过其下属的AbstractEndpoint类实现的,它实现了开启关闭服务,监听请求等功能。以下是部分代码的样例:
     public class AbstractEndpoint {
      ...
      protected void bind() {
         ... 
         serverSocket.bind(getInetAddress());
         ...
      }
      ...
     }
  1. 创建Request和Response对象: 之后会创建Request和Response对象,这个会在 org.apache.catalina.connector 包的 HttpProcessor类中实现,此类主要型成接收请求并创建 request 和 response 对象的任务。
     public class HttpProcessor {
         
         public void process(Socket socket) {
             ...
             Request request = new Request();
             Response response = new Response();
             response.setRequest(request);
             ...
         }
     }
  1. 解析请求: 连接器组件接收到请求后,会对请求做解析,并将解析结果存储到 Request 对象中,这个过程发生在 Connector的 CoyoteAdapter 类的 service 方法中。解析请求涉及请求行,请求头部以及请求体的解析,这个涉及到HttpRequestHeader, HttpRequestLine, HttpRequestBody 这几个类。
     public class CoyoteAdapter {
         ...
         public void service(Request req, Response res){
             ...
             connector.getService().getMapper().map(hostName, decodedURI, 
                     message.getMappingData());
             request.setMethod(req.method().toString());
             request.setQueryString(req.queryString().toString());
             ...
         }
     }
  1. 查找并执行Servlet: 请求解析完毕后,根据解析结果,会查找合适的 Servlet 来处理该请求,这个过程在StandardWrapper类的 allocate 方法中完成。最后会调用Servlet的service方法来处理请求。
     public class StandardWrapper {
         ...
         public Servlet allocate() {
             ...
             servlet = instanceManager.newInstance(getServletClass());
             ...
             servlet.service(request, response); 
             ...
         }
     }

Step 3: 查找对应的Servlet

Tomcat Servlet容器会根据HttpServletRequest对象的信息(例如URL、HTTP方法类型等)去寻找已经注册到容器中的对应的Servlet。

在Spring Boot中,这个过程是在ServletWebServerApplicationContext类中的prepareDispatcherServlet()方法中完成的,代码如下:

 private void prepareDispatcherServlet(ServletContext servletContext) {
     String servletName = getServletName();
     ApplicationContext applicationContext = createServletApplicationContext();
     ...
     DispatcherServlet servlet = new DispatcherServlet(applicationContext);
     ServletRegistration.Dynamic registration = servletContext.addServlet(servletName, servlet);
     registration.setLoadOnStartup(this.dispatcherServletInitParameters.getLoadOnStartup());
     registration.addMapping(this.dispatcherServletMapping);
     ...
 }

在这个方法中,创建了一个DispatcherServlet实例,并使用addServlet()方法注册到了Servlet容器中(Tomcat),并使用addMapping()方法设置了Servlet处理的URL路径。

Step 4: DispatcherServlet处理请求

找到对应的DispatcherServlet后,Tomcat将把HttpServletRequest对象传递给它。

Step 5: 路由到对应的Controller

DispatcherServlet接收到HttpServletRequest后,将会根据其中的URL信息,去寻找在Spring应用程序中注册的对应的Controller和处理的方法。

Step 6: Controller处理请求

找到对应的Controller和方法后,DispatcherServlet将调用这个方法,并传递HttpServletRequest中的信息。这个方法将处理请求,并返回一个ModelAndView对象。

Step 7: 视图解析和返回响应

DispatcherServlet将使用视图解析器,将ModelAndView对象解析为具体的视图,并返回HTTP响应。

以上就是Spring Boot处理HTTP请求的整个过程。在这个过程中,Spring Boot的自动配置让开发者不需要关心底层的处理细节,可以专注于编写业务代码。