Servlet 生命周期、工做原理-是单实例多线程

Servelet是单实例多线程的

参考:servlet单实例多线程模式

1、Servlet生命周期 

大体分为4部:Servlet类加载-->实例化-->服务-->销毁html

一、Web Client向Servlet容器(Tomcat)发出Http请求。java

二、Servlet容器接收Client端的请求。程序员

三、Servlet容器建立一个HttpRequest对象,将Client的请求信息封装到这个对象中。web

四、Servlet建立一个HttpResponse对象。apache

五、Servlet调用HttpServlet对象的service方法,把HttpRequest对象和HttpResponse对象做为参数传递给HttpServlet对象中。服务器

六、HttpServlet调用HttpRequest对象的方法,获取Http请求,并进行相应处理。多线程

七、处理完成HttpServlet调用HttpResponse对象的方法,返回响应数据。app

八、Servlet容器把HttpServlet的响应结果传回客户端。框架

        其中的3个方法说明了Servlet的生命周期:post

一、init():负责初始化Servlet对象。

二、service():负责响应客户端请求。

三、destroy():当Servlet对象退出时,负责释放占用资源。

  1. init():在Servlet的生命周期中,仅执行一次init()方法。它是在服务器装入Servlet时执行的,负责初始化Servlet对象。能够配置服务器,以在启动服务器或客户机首次访问Servlet时装入Servlet。不管有多少客户机访问Servlet,都不会重复执行init()。
  2. service():它是Servlet的核心,负责响应客户的请求。每当一个客户请求一个HttpServlet对象,该对象的Service()方法就要调用,并且传递给这个方法一个“请求”(ServletRequest)对象和一个“响应”(ServletResponse)对象做为参数。在HttpServlet中已存在Service()方法。默认的服务功能是调用与HTTP请求的方法相应的do功能。
  3. destroy(): 仅执行一次,在服务器端中止且卸载Servlet时执行该方法。当Servlet对象退出生命周期时,负责释放占用的资源。一个Servlet在运行service()方法时可能会产生其余的线程,所以须要确认在调用destroy()方法时,这些线程已经终止或完成。

大多数程序员都知道Servlet的生命周期,简单的归纳这就分为四步:servlet类加载--->实例化--->服务--->销毁。对这个过程只是肤浅了解下,对于servlet什么时候被销毁,仍是不太情楚。下面咱们描述一下Tomcat与Servlet是如何工做的,首先看下面的时序图.

 2、Servlet工做原理

一、首先简单解释一下Servlet接收和响应客户请求的过程,首先客户发送一个请求,Servlet是调用service()方法对请求进行响应的,经过源代码可见,service()方法中对请求的方式进行了匹配,选择调用doGet,doPost等这些方法,而后再进入对应的方法中调用逻辑层的方法,实现对客户的响应。在Servlet接口和GenericServlet中是没有doGet()、doPost()等等这些方法的,HttpServlet中定义了这些方法,可是都是返回error信息,因此,咱们每次定义一个Servlet的时候,都必须实现doGet或doPost等这些方法。

二、每个自定义的Servlet都必须实现Servlet的接口,Servlet接口中定义了五个方法,其中比较重要的三个方法涉及到Servlet的生命周期,分别是上文提到的init(),service(),destroy()方法。GenericServlet是一个通用的,不特定于任何协议的Servlet,它实现了Servlet接口。而HttpServlet继承于GenericServlet,所以HttpServlet也实现了Servlet接口。因此咱们定义Servlet的时候只须要继承HttpServlet便可。

三、Servlet接口和GenericServlet是不特定于任何协议的,而HttpServlet是特定于HTTP协议的类,因此HttpServlet中实现了service()方法,并将请求ServletRequest、ServletResponse 强转为HttpRequest 和 HttpResponse。 

对于Servlet容器(Tomcat)与HttpServlet是怎样进行交互的呢,看下类图

Servlet的框架是由两个Java包组成的:javax.servlet与javax.servlet.http。在javax.servlet包中定义了全部的Servlet类都必须实现或者扩展的通用接口和类。在javax.servlet.http包中定义了采用Http协议通讯的HttpServlet类。Servlet的框架的核心是javax.servlet.Servlet接口,全部的Servlet都必须实现这个接口。 

 

1、建立Servlet对象的时机

一、Servlet容器启动时:读取web.xml配置文件中的信息,构造指定的Servlet对象,建立ServletConfig对象,同时将ServletConfig对象做为参数来调用Servlet对象的init方法。

二、在Servlet容器启动后:客户首次向Servlet发出请求,Servlet容器会判断内存中是否存在指定的Servlet对象,若是没有则建立它,而后根据客户的请求建立HttpRequest、       HttpResponse对象,从而调用Servlet

     对象的service方法。

三、Servlet的类文件被更新后,从新建立Servlet

      Servlet容器在启动时自动建立Servlet,这是由在web.xml文件中为Servlet设置的<load-on-startup>属性决定

      的。从中咱们也能看到同一个类型的Servlet对象在Servlet容器中以单例的形式存在。

<servlet>
        <servlet-name>Init</servlet-name>
        <servlet-class>org.xl.servlet.InitServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
</servlet>

 

2、销毁Servlet对象的时机

一、Servlet容器中止或者从新启动:Servlet容器调用Servlet对象的destroy方法来释放资源。以上所讲的就是Servlet对象的生命周期。那么Servlet容器如何知道建立哪个Servlet对象?

Servlet对象如何配置?实际上这些信息是经过读取web.xml配置文件来实现的。

咱们来看一下web.xml文件中的Servlet对象的配置节信息 

<servlet>
    <servlet-name>action<servlet-name>
    <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
    <init-param>
        <param-name>config</param-name>
        <param-value>/WEB-INF/struts-config.xml</param-value>
    </init-param>
    <init-param>
        <param-name>detail</param-name>
        <param-value>2</param-value>
    </init-param>
    <init-param>
        <param-name>debug</param-name>
        <param-value>2</param-value>
    </init-param>
    <load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>action</servlet-name>
    <url-pattern>*.do</url-pattern>
</servlet-mapping>

 

下面对上面的配置节信息进行解析

servlet-name:Servlet对象的名称

servlet-class:建立Servlet对象所要调用的类

param-name:参数名称

param-value:参数值

load-on-startup:Servlet容器启动时加载Servlet对象的顺序

servlet-mapping/servlet-name:要与servlet中的servlet-name配置节内容对应

url-pattern:客户访问的Servlet的相对URL路径 

       当Servlet容器启动的时候读取<servlet>配置节信息,根据<servlet-class>配置节信息建立Servlet对象,同时根据<init-param>配置节信息建立HttpServletConfig对象,而后执行Servlet对象的init方法,而且根据<load-on-startup>配置节信息来决定建立Servlet对象的顺序,若是此配置节信息为负数或者没有配置,那么在Servlet容器启动时,将不加载此Servlet对象。当客户访问Servlet容器时,Servlet容器根据客户访问的URL地址,经过<servlet-mapping>配置节中的<url-pattern>配置节信息找到指定的Servlet对象,并调用此Servlet对象的service方法。   

 

参考:Servlet生命周期