Servlet的生命周期
牢记!!!
不建议在service方法中修改成员变量,在并发请求时,会引发线程安全问题
Servlet 生命周期
3. Servlet 实例创建:
- 由 Web 容器创建 Servlet 实例(在第一次请求或
loadOnStartup
时触发)。 - 如果在
web.xml
中或使用@WebServlet
注解中配置了loadOnStartup
属性,则该 Servlet 会在服务器启动时创建实例,而不等到第一次请求。 -
行为:
- Servlet 容器通过调用 Servlet 类的无参构造函数来创建实例。
- 注意:每个 Servlet 只会有一个实例,所有请求都共享这个实例。
2. 初始化:
- 调用
init()
方法完成 Servlet 的初始化。
public void init() throws ServletException {
// Servlet 初始化时的操作,如加载资源等
}
init()
方法用于执行一次性初始化操作,例如:读取配置文件、打开数据库连接等。- 该方法只会被调用一次,在 Servlet 实例创建后立即执行。
- 如果初始化失败,容器会抛出
ServletException
,并销毁该 Servlet。
3. 处理请求:
- 多次调用
service()
方法,每个请求都会被分发到对应的doGet()
或doPost()
等方法。
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 处理HTTP请求,分发给对应的doGet()、doPost()等方法
}
默认的 service()
方法会根据请求的类型(GET、POST、PUT 等)调用相应的处理方法(如 doGet()
、doPost()
等)。
- GET 请求:调用
doGet()
方法。 - POST 请求:调用
doPost()
方法。 - PUT 请求:调用
doPut()
方法。 - DELETE 请求:调用
doDelete()
方法。
请求的处理过程:
- 客户端发送请求到服务器(Servlet 容器)。
- Servlet 容器根据请求 URL,找到对应的 Servlet。
- 容器调用 Servlet 的
service()
方法。 service()
方法会进一步分发请求到对应的doGet()
、doPost()
等方法
4. 销毁:
当 Web 应用关闭、Servlet 容器关闭,或者 Servlet 被从容器中移除时,容器会调用 destroy()
方法来销毁 Servlet 实例。
- 调用
destroy()
方法,Servlet 被销毁,释放资源。public void destroy() { // 清理资源的代码,例如关闭数据库连接、释放内存等 }
该方法用于执行任何需要清理的操作,例如关闭数据库连接、释放文件资源等。
- 它只会被调用一次,当 Servlet 的生命周期结束时被触发。
- Servlet 容器销毁 Servlet 实例后,不会再处理任何新的请求。
-
注意:
- 一旦调用了
destroy()
,这个 Servlet 的实例会被垃圾回收。 - 在
destroy()
之后,容器不会再调用service()
方法,也不能再响应新的请求。
- 一旦调用了
生命周期中的重要概念:
-
单实例多线程:
- 每个 Servlet 在容器中是单实例的,所有请求都共享这个实例。因此,Servlet 的方法需要是线程安全的。
- 不要在 Servlet 中使用实例变量来保存与请求相关的数据,避免线程间数据混乱。
-
初始化和销毁只执行一次:
init()
和destroy()
只会在整个生命周期中分别调用一次。
DefaultServlet:
DefaultServlet
是由 Web 容器(如 Apache Tomcat)提供的一个默认 Servlet,用于处理静态资源的请求。当 Web 应用中没有其他 Servlet 匹配某个请求时,DefaultServlet
会负责响应这个请求,通常用于提供静态文件(如 HTML、CSS、JavaScript、图片等)给客户端。
DefaultServlet
的作用
-
处理静态资源:
DefaultServlet
主要用于处理和提供静态文件(如 HTML 页面、CSS 样式表、JavaScript 文件、图像等)。当请求的 URL 对应于服务器上的某个静态资源文件时,DefaultServlet
会负责将该文件返回给客户端。
-
作为兜底的处理器:
- 当其他 URL 没有匹配任何自定义的 Servlet 或 JSP 时,
DefaultServlet
会作为兜底处理器响应请求。 - 通常在
web.xml
中,DefaultServlet
会映射到/
,它会捕获所有没有被其他url-pattern
匹配的请求。
- 当其他 URL 没有匹配任何自定义的 Servlet 或 JSP 时,
-
不处理动态请求:
DefaultServlet
只用于提供静态资源,它不处理动态请求(如.jsp
、Servlet
的请求),这些动态请求会由专门的 Servlet 或 JSP 引擎处理。默认服务器启动,默认启动序号为1
为什么在使用 Spring MVC 框架时,DefaultServlet
会失效?
Spring MVC 的 DispatcherServlet
:
DispatcherServlet
是 Spring MVC 的前端控制器,它会拦截由url-pattern
匹配的所有请求。- 如果你配置了
DispatcherServlet
来拦截所有请求(如/
或/*
),它会覆盖DefaultServlet
,导致所有请求(包括静态资源请求)都会由DispatcherServlet
处理,而不是DefaultServlet
。 - 这意味着,静态资源(如 CSS、JS、图片等)的请求也会被 Spring 的
DispatcherServlet
捕获,而不会自动传递给DefaultServlet
进行处理。
默认情况下,Spring MVC 不处理静态资源:
- Spring MVC 默认不会自动处理静态资源的请求,因为它主要是为动态内容和业务逻辑服务的。
- 因此,如果
DispatcherServlet
接管了所有请求,静态资源的请求可能会返回 404 错误,或者因为没有相应的控制器处理这些资源而导致无法加载。
如何解决静态资源被拦截的问题?
为了让 Spring MVC 和 DefaultServlet
共存并正确处理静态资源请求,你可以采用以下几种方法:
配置 DefaultServletHandler
(推荐)
Spring MVC 提供了 DefaultServletHandler
,用于将静态资源的请求交给容器中的 DefaultServlet
来处理。这是最推荐的方式。
配置方法: 在 Spring 的配置文件(如 spring-servlet.xml
)中,添加如下配置:
<!-- 启用 DefaultServletHandler,将静态资源请求交给容器的 DefaultServlet 处理 -->
<mvc:default-servlet-handler />
解释:
<mvc:default-servlet-handler />
:启用这个配置后,Spring MVC 会将未被 Spring MVC 的控制器处理的请求(如静态资源)转发给 Web 容器的DefaultServlet
来处理。这意味着 Spring MVC 不会再拦截这些静态资源的请求,而是让容器的默认处理器(如 Tomcat 的DefaultServlet
)来处理它们。
原文地址:https://blog.csdn.net/gege_0606/article/details/142330109
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!