Spring Boot是如何处理HTTP请求的?
在Spring Boot中创建基本的REST控制器是个简单的过程 。通过使用一些注释,您可以封装所需的逻辑,让Spring Boot处理其余部分 。但是,这背后究竟发生了什么?本文将详细介绍Spring Boot如何处理HTTP请求的复杂性 。

文章插图
探索设置首先,来看一个示例控制器类:
@RestControllerclass GreetingController {@GetMApping("/greeting")fun getGreeting() = "hi there"}
在这个例子中,有一个单一的端点,返回一个基本的字符串响应 。要设置您的项目,请将以下依赖项添加到build.gradle文件中:implementation("org.springframework.boot:spring-boot-starter-web")
现在,使用Apache Tomcat运行应用程序 。./gradlew bootRun
Apache TomcatSpring Boot为我们启动了一个嵌入式Tomcat Web服务器,默认情况下监听8080端口:2023-09-10T19:07:52.604INFO 8712 --- [mAIn] o.s.b.w.embedded.tomcat.TomcatWebServer: Tomcat started on port(s): 8080 (http) with context path ''
Apache Tomcat是一个开源JAVA Servlet容器,实现了关键的Java企业(现在是Jakarta EE)标准 , 包括Jakarta Servlet、Jakarta Server Pages和Jakarta WebSocket 。在Spring中,它启动了一个Servlet容器,该容器监听默认的TCP端口8080 , 用于接收请求 。一旦有请求到达,我们可以观察到接收者和工作线程开始处理请求:

文章插图
【Spring Boot是如何处理HTTP请求的?】接受者线程负责接收传入请求并将其放入队列中 。但是,如果队列达到其容量 , 则接受者将拒绝其他请求 。另一方面,工作线程从接受者队列中检索请求,并在其专用线程堆栈中处理每个请求 。
我们目前有1个接受者和10个工作线程 。但是,请注意这些值可能会因我们的特定配置而有所不同 。由于我们没有修改任何配置参数,因此Spring已根据Spring Boot文档中概述的默认值自动为我们设置了默认值 。
需要考虑的一些重要配置参数是:
server.tomcat.accept-count=100 # Maximum queue length for incoming connection requests when all possible request processing threads are in use.server.tomcat.max-connections=10000 # Maximum number of connections that the server accepts and processes at any given time.server.tomcat.max-threads=200 # Maximum amount of worker threads.server.tomcat.min-spare-threads=10 # Minimum amount of worker threads.
此外 , 值得注意的是,我们使用非阻塞IO(NIO)线程 。这意味着单个线程可以管理多个连接并维护它们的持续时间,该持续时间由keepAlive参数确定 。要查看请求处理过程,请向我们的端点发送HTTP请求:
curl localhost:8080/greeting
您将观察到其中一个工作线程处理请求:
文章插图
Dispatcher servlet接下来介绍如何将请求路由到我们的控制器逻辑 。
在请求之后,您会注意到一个日志条目:
2023-09-10T19:07:58.604INFO 23948 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]: Initializing Spring DispatcherServlet 'dispatcherServlet'2023-09-10T19:07:58.292INFO 23948 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet: Initializing Servlet 'dispatcherServlet'2023-09-10T19:07:58.293INFO 23948 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet: Completed initialization in 1 ms
这表明已实例化DispatcherServlet类的一个实例来处理请求 。您可以在org.springframework.web.servlet包中轻松找到此类 。在此包中,您将发现DispatcherServlet实际上是扩展HttpServlet类的标准servlet 。它作为所有Spring基础架构的入口点,在由Web服务器管理的Web应用程序中使用 。在Spring Web应用程序中,在配置中定义DispatcherServlet时,Apache Tomcat容器将初始化此servlet并将我们的请求委托给它,利用其工作线程之一 。
请求映射DispatcherServlet中的中心方法是doService方法,它接收并指导我们的请求 。
您可能会想知道,它如何确定适当的类来处理此特定请求 。
答案在于它的handlerMappings字段,该字段存储实现HandlerMapping接口的类集合 。在DispatcherServlet实例化期间,此字段由initHandlerMappingsmethod初始化 。
每当我们使用方法级别的@RequestMapping注释定义新的@Controller类时 , Spring都会自动生成一个RequestMappingInfo类 。然后,将此生成的信息无缝地合并到handlerMappings属性中 。随后,我们的DispatcherServlet利用此数据进行精确的请求路由 。
推荐阅读
- Python小技巧:判断一个列表是否包含另一个列表的全部元素
- C++ 里 ++i 是原子操作吗?
- 什么是性能工程?
- 零信任不仅仅关乎安全,还是数字化转型的基础
- 很多主流项目都放弃了Java 8,背后的原因是什么
- 微服务是个坏主意吗?
- Spring Cloud 微服务系列之 ShardingSphere-Proxy 数据库代理
- 人工钻石是莫桑钻吗?莫桑钻可以人工合成吗?莫桑钻和钻石的区别是什么?
- 莫桑石是什么?值钱吗?
- 他能演会唱,是关海山徒弟罗嘉良好友,花百万为妻治癌,因爱复婚