自学内容网 自学内容网

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() 方法,也不能再响应新的请求。

生命周期中的重要概念:

  1. 单实例多线程

    • 每个 Servlet 在容器中是单实例的,所有请求都共享这个实例。因此,Servlet 的方法需要是线程安全的。
    • 不要在 Servlet 中使用实例变量来保存与请求相关的数据,避免线程间数据混乱。
  2. 初始化和销毁只执行一次

    • init()destroy() 只会在整个生命周期中分别调用一次。

 

 DefaultServlet:

DefaultServlet 是由 Web 容器(如 Apache Tomcat)提供的一个默认 Servlet,用于处理静态资源的请求。当 Web 应用中没有其他 Servlet 匹配某个请求时,DefaultServlet 会负责响应这个请求,通常用于提供静态文件(如 HTML、CSS、JavaScript、图片等)给客户端。

DefaultServlet 的作用

  1. 处理静态资源

    • DefaultServlet 主要用于处理和提供静态文件(如 HTML 页面、CSS 样式表、JavaScript 文件、图像等)。当请求的 URL 对应于服务器上的某个静态资源文件时,DefaultServlet 会负责将该文件返回给客户端。
  2. 作为兜底的处理器

    • 当其他 URL 没有匹配任何自定义的 Servlet 或 JSP 时,DefaultServlet 会作为兜底处理器响应请求。
    • 通常在 web.xml 中,DefaultServlet 会映射到 /,它会捕获所有没有被其他 url-pattern 匹配的请求。
  3. 不处理动态请求

    • DefaultServlet 只用于提供静态资源,它不处理动态请求(如 .jspServlet 的请求),这些动态请求会由专门的 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)!