icode icode
首页
  • Android学习

    • 📁基础内容
    • 📺AndroidCore
    • 🎨Android-UI
    • 🏖️Components
    • 📊Fragment
    • 🔗网络操作
    • 🔏异步机制
    • 📦数据存储
    • 🗃️Gradle
  • 学习笔记

    • 『框架』笔记
    • 『Kotlin』笔记
    • 《Vue》笔记
    • 《Git》学习笔记
    • 『Bug踩坑记录』
  • ListView
  • RecyclerView
  • ViewPager
  • Java笔记

    • 🟠JavaSE
    • 🟢JavaWeb
    • 🔴JavaEE
    • ⚪JavaTopic
    • 🍳设计模式
  • 计算机基础

    • 📌计算机网络
    • 🔍数据结构
    • 📦数据库
    • 💻OS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
  • 关于

    • 📫关于我
  • 收藏

    • 网站
    • 资源
    • Vue资源
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

iqqcode

保持对技术的探索实践与热爱
首页
  • Android学习

    • 📁基础内容
    • 📺AndroidCore
    • 🎨Android-UI
    • 🏖️Components
    • 📊Fragment
    • 🔗网络操作
    • 🔏异步机制
    • 📦数据存储
    • 🗃️Gradle
  • 学习笔记

    • 『框架』笔记
    • 『Kotlin』笔记
    • 《Vue》笔记
    • 《Git》学习笔记
    • 『Bug踩坑记录』
  • ListView
  • RecyclerView
  • ViewPager
  • Java笔记

    • 🟠JavaSE
    • 🟢JavaWeb
    • 🔴JavaEE
    • ⚪JavaTopic
    • 🍳设计模式
  • 计算机基础

    • 📌计算机网络
    • 🔍数据结构
    • 📦数据库
    • 💻OS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
  • 关于

    • 📫关于我
  • 收藏

    • 网站
    • 资源
    • Vue资源
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • JavaSE

  • JavaWeb

    • BootStrap

    • Cookie和Session

    • JavaScript

    • JDBC

    • JQuery

    • JSON

    • JSP

    • Maven

    • Servlet

      • Servlet执行原理
      • Servlet生命周期
        • Servlet生命周期
          • 1.Servlet中的生命周期方法
          • 2.Servlet工作原理
          • 3.容器与Web应用上下文的关系
          • 4.Web服务器工作流程
      • Servlet体系结构
      • Servlet之HTTP请求
      • Request对象
      • 登录案例
      • BeanUtils
      • Response响应
      • ServletContext对象
      • IDEA导入Eclipse SSM项目参考
    • Tomcat

    • XML

  • JavaEE

  • JavaTopic

  • 设计模式

  • 计算机基础

  • Java后端
  • JavaWeb
  • Servlet
iqqcode
2021-06-17
目录

Servlet生命周期

文章的内容比较基础,俺会继续补充深入的,冲冲冲...

# Servlet生命周期

# 1.Servlet中的生命周期方法

Servlet 加载——>实例化——>服务——>销毁

E:\MarkText\Cache-img 【图是借来的,原文链接 Servlet的生命周期简述 (opens new window)】

  • init( )

    在Servlet的生命周期中,仅执行一次init()方法。它是在服务器装入Servlet时执行的,负责初始化Servlet对象。可以在启动服务器或客户机首次访问时装入Servlet。无论有多少客户机访问Servlet,init()只执行一次。

  • service( ):

    执行多次。它是Servlet的核心,负责响应客户的请求。每当一个客户请求一个HttpServlet对象时,该对象的service()方法就要调用,而且传递给这个方法一个 “请求”(ServletRequest)对象和一个 “响应”(ServletResponse)对象作为参数。在HttpServlet中已存在service()方法。默认的服务功能是调用与HTTP请求的方法相应的do功能。

  • destroy( ):

    仅执行一次,在服务器端停止且卸载Servlet时执行该方法。当Servlet对象退出生命周期时,负责释放占用的资源。一个Servlet在运行service()方法时可能会产生其他的线程,因此需要确认在调用destroy()方法时,这些线程已经终止或完成。

# 1.1 创建

创建执行init()方法,只执行一次,加载资源

    <!--配置ServletMethods-->
    <servlet>
        <servlet-name>ServletMethods</servlet-name>
        <servlet-class>org.iqqcode.web.servlet.ServletMethods</servlet-class>
        <!--指定Servle的创建时机(在服务器启动时被创建)
                1.第一次被访问时创建
                    * <load-on-startup>的默认值为-1
                2.在服务器启动时创建
                    * <load-on-startup>的值为0或正整数
         -->
        <load-on-startup>-5</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>ServletMethods</servlet-name>
        <url-pattern>/ServletMethods</url-pattern>
    </servlet-mapping>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

<load-on-startup> 1</load-on-startup>启动时没有创建servlet,在启动后调用init()

<load-on-startup>-5</load-on-startup>启动时创建servlet,在启动前调用init()

指定Servle的创建时机(在服务器启动时被创建)

  • 第一次被访问时创建 <load-on-startup>的默认值为-1

  • 在服务器启动时创建 <load-on-startup>的值为0或正整数


Servlet的init()方法,只执行一次,说明一个Servlet在内存中只存在一个对象,Servlet是单例的(单例:一个类只能产生一个对象)

那么,为什么Servlet时单例的呢?因为多个用户同时访问时,可能存在线程安全问题。如果同时读,那么数据不会被修改,就没有问题。但是如果A在修改,B在读取,可能就会造成数据不一致的问题。

如何解决呢?

可能大家会想到加锁,但是没法通过同步方法来上锁,因为Servlet是定义了一个标准,我们是来实现的,不能再外部修改,在service()方法中无法实现。同步代码块上锁之后,一次只允许一个对象来访问资源,对于服务器来说性能低下。

解决:

尽量不要在Servlet中定义成员变量,即使定义了成员变量,也不要修改值。

如果将变量定义在方法中,为局部变量,此时对象在栈中,不共享只在此方法中有效。

//提供服务
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws  {
      int num = 0;
        System.out.println("Hello Servlet!");
}
1
2
3
4
5
6

# 1.2 提供服务

提供服务时执行service()方法,执行多次。每次访问Servlet时,service()方法都会被调用一次

参数 service(ServletRequest servletRequest, ServletResponse servletResponse)

ServletRequest & ServletResponse

对于每一个HTTP请求,servlet容器会创建一个封装了HTTP请求的ServletRequest实例传递给servlet的service方法,ServletResponse则表示一个Servlet响应,其隐藏了将响应发给浏览器的复杂性。通过ServletRequest的方法你可以获取一些请求相关的参数,而ServletResponse则可以将设置一些返回参数信息,并且设置返回内容。

# 1.3 被销毁

Servlet被销毁(服务器正常关闭)前执行destroy方法,只执行一次 ,释放资源

# 2.Servlet工作原理

当Web服务器接收到一个HTTP请求时,它会先判断请求内容——

  • 如果是静态网页数据,Web服务器将会自行处理,然后产生响应信息;

  • 如果牵涉到动态数据,Web服务器会将请求转交给Servlet容器。此时Servlet容器会找到对应的处理该请求的Servlet实例来处理,结果会送回Web服务器,再由Web服务器传回用户端。

在这里插入图片描述

针对同一个Servlet,Servlet容器会在第一次收到Http请求时建立一个Servlet实例,然后启动一个线程。第二次收到Http请求时,Servlet容器无须建立相同的Servlet实例,而是启动第二个线程来服务客户端请求。所以多线程方式不但可以提高Web应用程序的执行效率,也可以降低Web服务器的系统负担。

# 3.容器与Web应用上下文的关系

  • Tomcat就是容器,其它替代者有Jetty、JBoss等等。

  • JavaWeb应用就是包含了一组Servlet、JSP、HTML等各种文件的一个集合。就是一定要放在在WEB-INF 目录下(包含web.xml文件)。

下图的Tomcat的组成结构刚好可以解释Java web里面最常见的一些概念:

在这里插入图片描述

  • 顶层的Server元素代表Tomcat容器

  • 一个Server可以包含多个Service组件

  • 一个Service里面可以有多个负责接受与响应客户请求的Connector组件

  • 一个Service只能包含一个Engine组件

  • 一个Engine组件可以包含多个虚拟主机(Host)组件(localhost是默认创建的主机,你还可以创建更多的虚拟主机,并且只要把DNS指向这台机器,就可以访问这个虚拟主机的URL)

  • 一个Host组件可以包含多个Context。一个Context就代表一个Web应用。

容器在启动一个Web应用时就创建一个ServletContext对象和这个应用对应起来,并且这个对象和Web应用的生命周期一致。因此,可以利用这个对象来存储全局数据。

# 4.Web服务器工作流程

在这里插入图片描述

Servlet工作原理时序图

  1. Web Client 向Servlet容器(Tomcat)发出Http请求;
  2. Servlet容器接收Web Client的请求;
  3. Servlet容器创建一个HttpRequest对象,将Web Client请求的信息封装到这个对象中;
  4. Servlet容器创建一个HttpResponse对象;
  5. Servlet容器调用HttpServlet对象的service方法,把HttpRequest对象与HttpResponse对象作为参数传给 HttpServlet对象;
  6. HttpServlet调用HttpRequest对象的有关方法,获取Http请求信息;
  7. HttpServlet调用HttpResponse对象的有关方法,生成响应数据;
  8. Servlet容器把HttpServlet的响应结果传给Web Client;

Web应用的生命周期

  1. 启动阶段:加载Web应用的数据,创建ServletContext对象,对Filter和一些Servlet进行初始化。

  2. 运行阶段:所有的Servlet都处于待命状态,随时可以响应客户端的请求。

  3. 终止阶段:销毁各种对象和资源。

【参考文章】

  1. 说说Servlet 生命周期、工作原理 (opens new window)
  2. Servlet 工作原理详解 (opens new window)
  3. Servlet核心 (opens new window)
  4. Servlet 工作原理详解 (opens new window)
  5. Servlet核心 (opens new window)
编辑 (opens new window)
上次更新: 2021/06/27, 10:49:09
Servlet执行原理
Servlet体系结构

← Servlet执行原理 Servlet体系结构→

最近更新
01
匿名内部类
10-08
02
函数式接口
10-08
03
ARouter-Kotlin踩坑
10-05
更多文章>
Theme by Vdoing | Copyright © 2021-2023 iqqcode | MIT License | 备案号-京ICP备2021028793号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×