servlet何时被实例化?【转】

若是没有设置loadOnStartup,则第一次请求的时候实例化html

分三种状况:
loadOnStartup < 0 
即负数的状况下,web容器启动的时候不作实例化处理,servlet首次被调用时作实例化
这种状况和没有设置loadOnStartup是同样的。
loadOnStartup > 0
web容器启动的时候作实例化处理,顺序是由小到大,正整数小的先被实例化
loadOnStartup = 0
web容器启动的时候作实例化处理,至关因而最大整数,所以web容器启动时,最后被实例化java

 

servlet实例化 解惑程序员

原本一直觉得 servlet是在容器启动的时候就实例化的,但是后来仔细想过,若是有1千个servlet,那服务器启动的时候就要实例化一千个类,那就是要在内存(堆中)中建立一千个对象,一次建立这么多对象,对于内存(堆中)而言负载量至关的大,有可能就会出现《内存溢出》的异常,因此后来想一想,应该是在请求的时候才去实例化的吧,这样的话,对于容器而言不用启动的时候就加载那么多东西,感受这就是请求时才加载的根本缘由吧,纯属我的看法,但愿各位有不一样看法的提出来,你们一块儿讨论。web

 

servlet 销毁 解惑数据库

jdk api 的定义apache

destroy方法在容器移除servlet 时执行,一样只执行一次。这个方法会在全部的线程的service()方法执行完成或者超时后执行,调用这个方法后,容器不会再调用这个servlet的方法,也就是说容器再也不把请求发送给这个servlet。这个方法给servlet释放占用的资源的机会,一般用来执行一些清理任务api

 

Servlet容器中止或者从新启动:Servlet容器调用Servlet对象的destroy方法来释放资源服务器

 

引用1            如下是jt   198952 在csdn上的原帖多线程

 http://blog.csdn.net/jt198952/article/details/5656130app

 

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

 

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

二、Servlet容器接收Web Client的请求

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

四、Servlet容器建立一个HttpResponse对象

五、Servlet容器调用HttpServlet对象的service方法,把HttpRequest对象与HttpResponse对象做为参数传给 HttpServlet对象

六、HttpServlet调用HttpRequest对象的有关方法,获取Http请求信息

七、HttpServlet调用HttpResponse对象的有关方法,生成响应数据

八、Servlet容器把HttpServlet的响应结果传给Web Client

 

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

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

 

在Servlet接口中定义了5个方法,

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

一、init方法:负责初始化Servlet对象。

二、service方法:负责响应客户的请求。

三、destroy方法:当Servlet对象退出生命周期时,负责释放占用的资源。

 

1、建立Servlet对象的时机

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

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

三、Servlet的类文件被更新后,从新建立ServletServlet容器在启动时自动建立Servlet,这是由在web.xml文件中为Servlet设置的<load-on-startup>属性决定

的。从中咱们也能看到同一个类型的Servlet对象在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方法。

 

引用2

http://blog.sina.com.cn/s/blog_5198c7370100cwrz.html

Servlet的生命周期定义了一个Servlet如何被加载、初始化,以及它怎样接收请求、响应请求、提供服务。 
  在代码中,Servlet生命周期由接口javax.servlet.Servlet定义。全部的Java Servlet 必须直接或间接地实现javax.servlet.Servlet接口,这样才能在Servlet Engine上运行。Servlet Engine提供network Service,响应MIME request,运行Servlet Container。 javax.servlet.Servlet接口定义了一些方法,在Servlet 的生命周期中,这些方法会在特定时间按照必定的顺序被调用。以下图所示。 
  servlet的定义及其生命周期 
   Servlet的生命周期
  Servlet 如何被加载(Load)、被实例化(Instantiated) 
  Servlet Engine 负责实例化和加载Servlet,这个过程能够在Servlet Engine 加载时执行,能够在Servlet 响应请求时执行,也能够在二者之间的任什么时候候执行(配置为load on start up的 servlet是在容器启动时被加载的)。 
  Servlet如何被初始化(Initialized) 
  Servlet Engine 加载好Servlet 后,必需要初始化它。初始化时Servlet 能够从数据库里读取初始数据,创建JDBC Connection,或者创建对其余有价值的资源的引用。 
  在初始化阶段,Init( )方法被调用。这个方法在javax.servlet.Serlet接口中定义。Init( )方法以一个Servlet 配置文件(ServletConfig 型)为参数。Servlet configuration 对象由Servlet Engine 实现,可让Servlet 从中读取一些name-value对的参数值。ServletConfig对象还可让Servlet接受一个Servlet Context对象。 
  Servlet 如何处理请求 
  Servlet 被初始化之后,就处于能响应请求的就绪状态。每一个对Servlet 的请求由一个Servlet Request 对象表明。Servlet 给客户端的响应由一个Servlet Response对象表明。当客户端有一个请求时,Servlet Engine 将ServletRequest 和ServletResponse对象都转发给Servlet,这两个对象以参数的形式传给Service方法。这个方法由javax.servlet.Servlet定义并由具体的Servlet 实现。 
  Servlet还能够实现 ServletRequest 和ServletResponse接口。ServletRequest接口可让Servlet 获取客户端请求中的参数,如form data、request信息、协议类型,等等。Servlet 能够从ServletInputStream流中读取request 数据。ServletResponse接口容许Servlet设置response headers和status codes。实现这个接口可使Servlet能访问ServletOutputStream流用来向客户端返回数据。 
  Servlet如何被释放 
  Servlet Engine 没有必要在Servlet 生命周期的每一段时间内都保持Servlet的状态。Servlet Engine能够随时随意使用或释放Servlet。所以,你不能依赖Servlet class或其成员存储信息。当Servlet Engine判断一个Servlet应当被释放时(好比说Engine准备Shut down 或须要回收资源),Engine必须让Servlet 能释放其正在使用的任何资源,并保存持续性的状态信息。这些能够经过调用Servlet的destroy方法实现。 在Servlet Engine 释放一个Servlet 之前,必须让其完成当前实例的service方法或是等到timeout(若是Engine定义了timeout)。当Engine释放一个Servlet之后,Engine将不能再将请求转发给它,Engine必须完全释放该Servlet并将其标明为可回收的(给garbage collection)。 
  在Servlet API中最重要的是Servlet interface。全部的Servlets执行这个interface的方式有不少种:或者是直接的,或者经过extending这个class执行它,如 HttpServlet。这个Servlet interface 提供并安排Servlet与客户端联系的方法。Servlet 编写者能够在他们开发Servlet程序时提供更多一些或全部这样的方法。 
  当一个Servlet接收来自客户端的调用请求时,它接收两个对象:一个是ServletRequest,另一个是ServletResponse。这个ServletRequest class 归纳从客户端到服务器之间的联系,而 ServletResponse class 归纳从Servlet返回客户端的联系。 
  ServletRequest interface 能够获取到这样一些信息,如由客户端传送的参数名称,客户端正在使用的协议,产生请求而且接收请求的服务器远端主机名。它也提供获取数据流的Servlet、ServletInputStream,这些数据是客户端引用中使用HTTP POST和PUT方法递交的。一个ServletRequest的子类可让Servlet获取更多的协议特性数据。 
  例如,HttpServletRequest 包含获取HTTP-specific头部信息的方法。ServletResponse interface 给出相应客户端的Servlet方法。它容许Servlet设置内容长度和回应的MIME类型,而且提供输出流ServletOutputStream,经过编写者能够发回相应数据。ServletResponse子类能够给出更多protocol-specific容量的信息。例如,HttpServletResponse 包含容许Servlet操做HTTP-specific头部信息的方法。

 

 

servlet与cgi的区别在于服务器的进程中,servlet是经过多线程的方式运行service方法,一个servlet实例能够服务于多个请求,

     而且其实例通常不会销毁,而cgi对每一个请求都产生新的进程,服务完成后就销毁,因此,cgi效率低于servlet。

 

 

总结与运用:

 

在实践中能够配置一个load on start up 的Servlet,它随服务器启动而初始化,在其init方法中启用一些参数设置,例如把某些变量存入ServletContext,这样之后在其余Servlet中就能够得到该参数了;而在其destroy中写入一些资源回收的代码,当服务器关闭时就能够自动关闭相遇的资源了。
相关文章
相关标签/搜索