Servlet生命周期,

Servlet生命周期,

Servlet是运行在Web服务器的程序,它是作为来自Web浏览器和其他HTTP客户端的请求和HTTP服务器上数据库或应用程序的中间层。

一、Servlet简介及概念

  Servlet是sun公司提供的一门用于开发动态web资源的技术。
  Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向浏览器输出数据),需要完成以下2个步骤:
vnsc威尼斯城官方网站,  1、编写一个Java类,实现HttpServlet接口。
  2、把开发好的Java类部署到web服务器中。
  按照一种约定俗成的称呼习惯,通常我们也把实现了servlet接口的java程序,称之为Servlet。

###生命周期全过程:

  1. 实例化:Servlet 容器创建 Servlet 的实例

  2. 初始化:该容器调用 init() 方法

  3. 服务:如果请求 Servlet,则容器调用service()方法

  4. 销毁:销毁实例之前调用 destroy() 方法

  5. 释放:垃圾回收

一、架构图

1. 生命周期


1.1 Servlet接口实现类

  Servlet接口SUN公司定义了两个默认实现类,分别为:GenericServlet、HttpServlet。

  HttpServlet指能够处理HTTP请求的servlet,它在原有Servlet接口上添加了一些与HTTP协议处理方法,它比Servlet接口的功能更为强大。因此开发人员在编写Servlet时,通常应继承这个类,而避免直接去实现Servlet接口。
  HttpServlet在实现Servlet接口时,覆写了service方法,该方法体内的代码会自动判断用户的请求方式,如为GET请求,则调用HttpServlet的doGet方法,如为Post请求,则调用doPost方法。因此,开发人员在编写Servlet时,通常只需要覆写doGet或doPost方法,而不要去覆写service方法。

 

 

1.1. Servlet生命周期

servlet是一个基于java技术的WEB组件,运行在服务器端,我们利用
sevlet可以很轻松的扩展WEB服务器的功能,使它满足特定的应用需要。servlet由servlet容器管理,servlet容器也叫
servlet引擎,是servlet的运行环境,给发送的请求和响应提供网络服务。

 

1)容器装载servlet(容器装载servlet时,会根据web.xml配置判断是否对实例初始化,否则等待http第一次请求servlet的时候,才调用init()进行初始化,并执行相应service操作)

2)创建servlet实例,并初始化对应的init()方法(仅执行一次)

3)接收客户Http请求,调用并执行相应的service()方法(doGet或doPOST),(执行多次)

4)在服务端停止服务或应用关闭时执行destroy()方法销毁servlet实例(仅执行一次)

注:如果是多线程的情况下,必须要确保所有所有线程都终止。

vnsc威尼斯城官方网站 1

测试源码servlet1.java

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class servlet1 extends HttpServlet{
    @Override
    public void init() throws ServletException {
        System.out.println("我被初始化了");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("我被调用了");
    }

    @Override
    public void destroy() {
        System.out.println("我被销毁了");
    }
}

Web.xml配置

 

 1 <web-app>
 2   <!-- servlet实例 -->
 3   <servlet>
 4     <servlet-name>servlet1</servlet-name>
 5     <servlet-class>study.myServlet.servlet1</servlet-class>
 6     <load-on-startup>1</load-on-startup>
 7   </servlet>
 8   <servlet-mapping>
 9     <servlet-name>servlet1</servlet-name>
10     <url-pattern>/hello</url-pattern>
11   </servlet-mapping>
12 </web-app>

 

1)其中配置了<load-on-startup>1</load-on-startup>
表示在容器启动的时候就实例化该servlet,其中的数字越小表示启动优先级别越高,

2)servlet的生命周期的销毁顺序和启动顺序相反。

 

Servlet的生命周期

 它的生命周期可以被定义为从创建到销毁的过程,以下是Servlet遵循的过程

1.Servlet 通过调用 init () 方法进行初始化。

2.Servlet 调用 service() 方法来处理客户端的请求。

3.Servlet 通过调用 destroy() 方法终止(结束)。

4.Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。

package com.wj.servlet;

import java.io.IOException;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;


public class ServletDemo1 implements Servlet{

    //实例化
    public ServletDemo1(){
        System.out.println("**********实例化**********");
    }

    //初始化   在Servlet第一次访问的时候会调用 init方法
    public void init(ServletConfig config) throws ServletException {
        System.out.println("**********初始化**********");
    }

    //服务    每次访问都会调用    
    public void service(ServletRequest req, ServletResponse res)
                throws ServletException, IOException {
            System.out.println("**********服务**********");
    }

    //销毁
    public void destroy() {
        System.out.println("**********销毁**********");
    }
    public ServletConfig getServletConfig() {
        return null;
    }

    public String getServletInfo() {
        return null;
    }

}

二、Servlet的运行过程

vnsc威尼斯城官方网站 2

http的get请求根据url找到<url-pattern>配置的地址,然后找到<servlet-class>中的包下的servlet类,再执行servlet类中的doGet()或doPost方法。三、servlet执行流程:Servlet的生命周期可以分为四个阶段,装载类及创建实例阶段、初始化阶段、服务阶段和实例销毁阶段。Servlet程序是由WEB服务器调用,web服务器收到客户端的Servlet访问请求后:
  ①Web服务器首先检查是否已经装载并创建了该Servlet的实例对象。如果是,则直接执行第④步,否则,执行第②步。
  ②装载并创建该Servlet的一个实例对象。 
  ③调用Servlet实例对象的init()方法。
  ④创建一个用于封装HTTP请求消息的HttpServletRequest对象和一个代表HTTP响应消息的HttpServletResponse对象,然后调用Servlet的service()方法并将请求和响应对象作为参数传递进去。
  ⑤WEB应用程序被停止或重新启动之前,Servlet引擎将卸载Servlet,并在卸载之前调用Servlet的destroy()方法。 执行流程如下: 

 

 vnsc威尼斯城官方网站 3

 

1、创建servlet实例:

在默认情况下Servlet实例是在第一个请求到来的时候创建,以后复用。如果有的Servlet需要复杂的操作需要在初始化时完成,比如打开文件、初始化网络连接等,可以通知服务器在启动的时候创建该Servlet的实例。具体配置如下:

   
<servlet>
     
<servlet-name>TimeServlet</servlet-name>
     
<servlet-class>com.allanlxf.servlet.basic.TimeServlet</servlet-class>
      <load-on-startup>1</load-on-startup>
    
</servlet>

servlet的配置都是在web.xml文件中配置的。

 

2、初始化

       
一旦Servlet实例被创建,Web服务器会自动调用init(ServletConfig
config)方法来初始化该Servlet。其中方法参数config中包含了Servlet的配置信息,比如初始化参数,该对象由服务器创建。

2.1 如何配置Servlet的初始化参数?

  
在web.xml中该Servlet的定义标记中,比如:

   
<servlet>
        
<servlet-name>TimeServlet</servlet-name>
        
<servlet-class>com.allanlxf.servlet.basic.TimeServlet</servlet-class>
        <init-param>
            <param-name>user</param-name>
            <param-value>username</param-value>
       </init-param>
       <init-param>
           <param-name>blog</param-name>
           <param-value>;
       </init-param>
    </servlet>

配置了两个初始化参数user和blog它们的值分别为username和http://。。。,
这样以后要修改用户名和博客的地址不需要修改Servlet代码,只需修改配置文件即可。

2.2
如何读取Servlet的初始化参数?

      
ServletConfig中定义了如下的方法用来读取初始化参数的信息:

       public String
getInitParameter(String name)

         
参数:初始化参数的名称。
         
返回:初始化参数的值,如果没有配置,返回null。

2.3
init(ServletConfig)方法执行次数

       在Servlet的生命周期中,该方法执行一次。

2.4
init(ServletConfig)方法与线程

     该方法执行在单线程的环境下,所以是线程安全的,因此开发者不用考虑线程安全的问题。

2.5init(ServletConfig)方法与异常

   该方法在执行过程中可以抛出ServletException来通知Web服务器Servlet实例初始化失败。一旦ServletException抛出,Web服务器不会将客户端请求交给该Servlet实例来处理,而是报告初始化失败异常信息给客户端,该Servlet实例将被从内存中销毁。如果在来新的请求,Web服务器会创建新的Servlet实例,并执行新实例的初始化操作

 

3、服务

   
一旦Servlet实例成功创建及初始化,该Servlet实例就可以被服务器用来服务于客户端的请求并生成响应。在服务阶段Web服务器会调用该实例的service(ServletRequest
request, ServletResponse
response)方法,request对象和response对象有服务器创建并传给Servlet实例。request对象封装了客户端发往服务器端的信息,response对象封装了服务器发往客户端的信息。

I. service()方法的职责

    
service()方法为Servlet的核心方法,客户端的业务逻辑应该在该方法内执行,典型的服务方法的开发流程为:

   
解析客户端请求-〉执行业务逻辑-〉输出响应页面到客户端

II.service()方法与线程

    
为了提高效率,Servlet规范要求一个Servlet实例必须能够同时服务于多个客户端请求,即service()方法运行在多线程的环境下,Servlet开发者必须保证该方法的线程安全性。

III.service()方法与异常

    
service()方法在执行的过程中可以抛出ServletException和IOException。其中ServletException可以在处理客户端请求的过程中抛出,比如请求的资源不可用、数据库不可用等。一旦该异常抛出,容器必须回收请求对象,并报告客户端该异常信息。IOException表示输入输出的错误,编程者不必关心该异常,直接由容器报告给客户端即可。

编程注意事项说明:

1) 当Server
Thread线程执行Servlet实例的init()方法时,所有的Client Service
Thread线程都不能执行该实例的service()方法,更没有线程能够执行该实例的destroy()方法,因此Servlet的init()方法是工作在单线程的环境下,开发者不必考虑任何线程安全的问题。

2)
当服务器接收到来自客户端的多个请求时,服务器会在单独的Client Service
Thread线程中执行Servlet实例的service()方法服务于每个客户端。此时会有多个线程同时执行同一个Servlet实例的service()方法,因此必须考虑线程安全的问题。

3)
请大家注意,虽然service()方法运行在多线程的环境下,并不一定要同步该方法。而是要看这个方法在执行过程中访问的资源类型及对资源的访问方式。分析如下:

     i.
如果service()方法没有访问Servlet的成员变量也没有访问全局的资源比如静态变量、文件、数据库连接等,而是只使用了当前线程自己的资源,比如非指向全局资源的临时变量、request和response对象等。该方法本身就是线程安全的,不必进行任何的同步控制。

      ii.
如果service()方法访问了Servlet的成员变量,但是对该变量的操作是只读操作,该方法本身就是线程安全的,不必进行任何的同步控制。

      iii.
如果service()方法访问了Servlet的成员变量,并且对该变量的操作既有读又有写,通常需要加上同步控制语句。

      iv.
如果service()方法访问了全局的静态变量,如果同一时刻系统中也可能有其它线程访问该静态变量,如果既有读也有写的操作,通常需要加上同步控制语句。

      v.
如果service()方法访问了全局的资源,比如文件、数据库连接等,通常需要加上同步控制语句。

 

4、销毁

    
当Web服务器认为Servlet实例没有存在的必要了,比如应用重新装载,或服务器关闭,以及Servlet很长时间都没有被访问过。服务器可以从内存中销毁(也叫卸载)该实例。Web服务器必须保证在卸载Servlet实例之前调用该实例的destroy()方法,以便回收Servlet申请的资源或进行其它的重要的处理。

 
Web服务器必须保证调用destroy()方法之前,让所有正在运行在该实例的service()方法中的线程退出或者等待这些线程一段时间。一旦destroy()方法已经执行,Web服务器将拒绝所有的新到来的对该Servlet实例的请求,destroy()方法退出,该Servlet实例即可以被垃圾回收。

四、servlet解析客户端http请求流程图:

vnsc威尼斯城官方网站 4

1.    
web客户向Servlet容器发出HTTP请求;

2.    
Servlet容器解析web的HTTP请求.

3.    
Servlet容器创建一个HttpServletRequest对象,在这个对象中封装了http请求信息;

4.    
Servlet容器创建一个HttpServletResponse对象;

5.    
Servlet容器(如果访问的该servlet不是在服务器启动时创建的,则先创建servlet实例并调用init()方法初始化对象)调用HttpServlet的service()方法,把HttpServletRequest和HttpServletResponse对象为service方法的参数传给HttpServlet对象;

  1.  
      service方法再根据请求方式分别调用doXXX方法。

7.   
Servlet容器把HttpServlet的响应结果传给web客户. 

 

 

四、Tomcat装载servlet三种方法:

1、Serlvet容器启动时自动装载某些Servlet,实现它只需要在web.xml文件中<servlet>  </servlet>之间添加<load-on-startup>1</load-on-startup>,数字越小,优先级越大。

2、在Servlet容器启动时,客户首次向Servlet发送请求

3、Servlet类文件被更新后,重新装载Servlet

 

 

参考文献:

vnsc威尼斯城官方网站 5

1.2. Filter生命周期

 

Filter(拦截器)主要对web服务器所管理的所有资源(包括:JSP,Servlet,静态图片)进行拦截和过滤处理,如果配置了/*,表示拦截所有请求,每次请求都会先调用Filter的doFilter方法进行处理。

 

1)服务器启动加载过滤器实例并调用init()方法,(过滤器实例的加载优先级高于servlet)

 

2)每一次请求都会事先调用doFilter()进行过滤处理

 

3)停止服务时执行destroy()销毁过滤器

 

 

Web.xml配置文件

 

 1 <filter>
 2     <filter-name>filter1</filter-name>
 3     <filter-class>study.myFilter.filter1</filter-class>
 4     <!-- 过滤参数 -->
 5     <init-param>
 6       <param-name>includeString</param-name>
 7       <param-value>.do;.jsp</param-value>
 8     </init-param>
 9   </filter>
10   <filter-mapping>
11     <filter-name>filter1</filter-name>
12     <url-pattern>/*</url-pattern>
13   </filter-mapping>

 

Filter1.java

 1 import javax.servlet.Filter;
 2 import javax.servlet.FilterChain;
 3 import javax.servlet.FilterConfig;
 4 import javax.servlet.ServletException;
 5 import javax.servlet.ServletRequest;
 6 import javax.servlet.ServletResponse;
 7 import javax.servlet.http.HttpServletRequest;
 8 
 9 public class filter1 implements Filter {
10     private FilterConfig Config;
11 
12 
13     public void init(FilterConfig filterConfig) throws ServletException {
14         Config = filterConfig;
15         System.out.println("1过滤器初始化成功");
16     }
17 
18     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
19         HttpServletRequest hrequest = (HttpServletRequest) servletRequest;
20 
21         //过滤资源后缀参数,获取web.xml配置文件的的<param-name>includeString</param-name>的参数值value
22         String includeStrings = Config.getInitParameter("includeString");
23         String stringList[] = includeStrings.split(";");
24 
25         //判断请求链接是否符合过滤要求的后缀
26         if(! this.isContains(hrequest.getRequestURI(),stringList)){
27             filterChain.doFilter(servletRequest,servletResponse);
28             System.out.println("1执行过滤失败");
29             return;
30         }
31         System.out.println("1执行过滤成功");
32     }
33 
34     //判断是否存在符合的后缀
35     public static boolean isContains(String container, String[] regx) {
36         boolean result = false;
37 
38         for (int i = 0; i < regx.length; i++) {
39             if (container.indexOf(regx[i]) != -1) {
40                 return true;
41             }
42         }
43         return result;
44     }
45 
46     public void destroy() {
47         System.out.println("1销毁过滤器");
48     }
49 }

 有了Filter拦截器,web服务器在每次调用资源之前都会执行一遍doFilter()方法,web服务器在调用doFilter方法时,会传递一个filterChain对象进来,filterChain对象是filter接口中最重要的一个对象,它也提供了一个doFilter方法,开发人员可以根据需求决定是否调用此方法,调用该方法,则web服务器就会调用web资源的service方法,即web资源就会被访问,否则web资源不会被访问。

 

 

Filter的拦截匹配模式xml配置:

 

 1 <filter-mapping>
 2     <filter-name>filter1</filter-name>
 3     <url-pattern>/*</url-pattern><!-- 拦截所有请求 -->
 4   </filter-mapping>
 5 
 6   <!-- 匹配后缀名 -->
 7   <filter-mapping>
 8     <filter-name>filter1</filter-name>
 9     <url-pattern>*.jsp</url-pattern>
10     <url-pattern>*.do</url-pattern>
11     <url-pattern>*.html</url-pattern>
12   </filter-mapping>
13 
14   <!-- 根目录请求路径过滤 -->
15   <filter-mapping>
16     <filter-name>filter1</filter-name>
17     <url-pattern>/kk/hello</url-pattern>
18     <url-pattern>/kk/*</url-pattern>
19   </filter-mapping>
20 
21   <!-- 匹配单一路径-->
22   <filter-mapping>
23     <filter-name>filter1</filter-name>
24     <url-pattern>/hello.html</url-pattern>
25   </filter-mapping>

 

1. 生命周期 1.1. Servlet
生命周期 servlet 是一个基于 java 技术的 WEB
组件,运行在服务器端,我们利用 sevlet 可以很轻松的扩…

init方法

一般情况下init只会被调用一次,在后续的网络请求都不会别调用,因此我们可以在init方法中初始化一些东西O(∩_∩)O哈哈哈~’

servlet执行流程和生命周期

javaweb学习总结(五)——Servlet开发(一)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

servlet的执行过程:

service方法

service方法是执行任务的重要方法,一般用来处理客户端的请求和给客户端响应,每次请求服务器都会执行service方法

  Step1:HTTP请求被服务器委派到Servlet容器

destroy方法

该方法一般是应用程序卸载,或者服务器停止的时候调用,只会执行一次

  Step2:Servlet加载Servlet

  Step3:Servlet
容器处理由多个线程产生的多个请求,每个线程执行一个单一的 Servlet 实例的
service() 方法

 

二、Servlet中方法:

1、init()

  init 方法被设计成只调用一次。它在第一次创建 Servlet
时被调用,在后续每次用户请求时不再调用。因此,它是用于一次性初始化。

  Servlet 创建于用户第一次调用对应于该 Servlet 的 URL
时,但是您也可以指定 Servlet 在服务器第一次启动时被加载。

  当用户调用一个 Servlet 时,就会创建一个 Servlet
实例,每一个用户请求都会产生一个新的线程,适当的时候移交给 doGet 或
doPost 方法。init() 方法简单地创建或加载一些数据,  这些数据将被用于
Servlet 的整个生命周期。

2、servic()

  service() 方法是执行实际任务的主要方法。Servlet 容器(即 Web
服务器)调用 service()
方法来处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端。

  每次服务器接收到一个 Servlet
请求时,服务器会产生一个新的线程并调用服务。service() 方法检查 HTTP
请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用
     doGet、doPost、doPut,doDelete 等方法。

3、destroy()

  destroy() 方法只会被调用一次,在 Servlet
生命周期结束时被调用。destroy() 方法可以让您的 Servlet
关闭数据库连接、停止后台线程、把 Cookie
列表或点击计数器写入到磁盘,并  执行其他类似的清理活动。在调用
destroy() 方法之后,servlet 对象被标记为垃圾回收。

相关文章