原文同步发表至个人博客【夜月归途】

原文链接:http://www.guitu18.com/se/java/2018-07-22/19.html

作者:夜月归途
出处:http://www.guitu18.com/
本博客中未标明转载的文章归作者夜月归途和博客园所有。
欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

Servlet生命周期和加载机制

查看Servlet3.1源码,其接口定义如下:

package javax.servlet;
public interface Servlet {
public void init(ServletConfig config)
throws ServletException;
public ServletConfig getServletConfig();
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException;
public String getServletInfo();
public void destroy();
}

init(ServletConfig config);

init方法在容器启动时会被容器调用,且只会被调用一次;
调用的时机是跟Servlet的配置项'load-on-startup'有关系的;

<servlet>
<servlet-name>springmvcdemo</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<load-on-startup>1</load-on-startup>:配置的值如果不小于0,那么标识容器在启动时就会加载这个Servlet,配置的值越小,加载的优先级越高;如果没有配置或者配置的值小于0时,容器会在该Servlet第一次被调用时才会被加载;不论哪种配置,init方法只会被调用一次;

init方法的参数,是容器传进去的;我们在web.xml中配置的contextConfigLocation参数,就保存在ServletConfig中;

这项参数我们不配置的话,它有默认值:WEB-INF/${ServletName}-servlet.xml,变量${ServletName}是xml中配置的'servlet-name';

getServletConfig();

getServletConfig方法用于获取ServletConfig;

service(ServletRequest req, ServletResponse res);

service方法用于具体处理一个请求;每次访问,都会执行一次,server方法内部会根据请求方式的不同,调用不同的doXXX方法;

getServletInfo();

getServletInfo方法可以获取一些Servlet相关的信息,如作者、版权等;这个方法需要自己实现,默认返回空字符串;

destroy();

destroy方法主要用于Servlet销毁时释放资源,同init一样只会被调用一次;

Servlet生命周期测试demo

  1. 新建web工程,创建三个都实现Servlet接口的ServletDemo对象;
    这里创建的分别是Servlet1,Servlet2,Servlet3,代码都是一样的只贴上Servlet1的代码;

    package com.guitu18.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 Servlet_1 implements Servlet { @Override
    public void destroy() {
    System.out.println("Servlet_1:destroy()执行销毁...");
    } @Override
    public ServletConfig getServletConfig() {
    return null;
    } @Override
    public String getServletInfo() {
    return null;
    } @Override
    public void init(ServletConfig arg0) throws ServletException {
    System.out.println("Servlet_1:init()执行初始化...");
    } @Override
    public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {
    System.out.println("Servlet_1:service()执行中...");
    } }
  2. web.xml配置如下:

    <servlet>
    <servlet-name>servlet_1</servlet-name>
    <servlet-class>com.guitu18.servlet.Servlet_1</servlet-class>
    </servlet>
    <servlet-mapping>
    <servlet-name>servlet_1</servlet-name>
    <url-pattern>/servlet_1</url-pattern>
    </servlet-mapping>
    <servlet>
    <servlet-name>servlet_2</servlet-name>
    <servlet-class>com.guitu18.servlet.Servlet_2</servlet-class>
    <load-on-startup>2</load-on-startup>
    </servlet>
    <servlet-mapping>
    <servlet-name>servlet_2</servlet-name>
    <url-pattern>*.guitu18</url-pattern>
    </servlet-mapping>
    <servlet>
    <servlet-name>servlet_3</servlet-name>
    <servlet-class>com.guitu18.servlet.Servlet_3</servlet-class>
    <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
    <servlet-name>servlet_3</servlet-name>
    <url-pattern>/abc/*</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
    <servlet-name>servlet_2</servlet-name>
    <url-pattern>/servlet_4</url-pattern>
    </servlet-mapping>

    我在xml中分别配置了这三个Servlet,配置了4个servlet-mapping,其中'/servlet2.guitu'和'/servlet4'都是指向servle_2的;
    这里就涉及到Servlet中<url-pattern>的配置方式了,一共有3种:

    1. 完全路径匹配
      以'/'开始;比如:/servlet_1
    2. 目录匹配
      以'/'开始,以'/'结束;比如:/abc/
    3. 扩展名匹配
      不能以'/'开始,要以''开始;比如:.guitu18

    为了是匹配时不产歧义,这三种匹配方式是有优先级的:
    完全路径匹配 > 目录匹配 > 扩展名匹配

  3. 启动项目:
    因为Servlet2和Servlet3都配置了<load-on-startup>项,且配置的值不小于0,所以在项目启动时,Servlet2和Servlet3就会被初始化,控制台输出:

    Servlet_3:init()执行初始化...
    Servlet_2:init()执行初始化...

    这里看出,Servlet3比Servlet2有限初始化,因为Servlet_3配置的<load-on-startup>的值比Servlet2小,所以优先被加载;Servlet1因为没有配置<load-on-startup>所以只有其第一次被访问时才会被加载初始化;

    访问Servlet1的地址:http://localhost:8080/servletdemo/servlet1

    Servlet_1:init()执行初始化...
    Servlet_1:service()执行中...

    此时Servlet_1才被初始化;

  4. Servlet对象销毁 现在关闭Tomcat服务,Servlet对象会被销毁;

    Servlet_2:destroy()执行销毁...
    Servlet_3:destroy()执行销毁...
    Servlet_1:destroy()执行销毁...

    可以看出销毁的顺序和加载的顺序相同,优先被加载的也会最先被销毁;

JaveWeb学习之Servlet(一):Servlet生命周期和加载机制的更多相关文章

  1. 整理ViewController的生命周期和加载过程

    按照执行顺序排列 - initWithCoder:通过nib文件初始化时触发 - awakeFromNib:nib文件被加载的时候,会发送一个awakeFromNib的消息到nib文件中的每个对象 p ...

  2. Java Web学习总结(9)——servlet和Jsp生命周期解读

    一.servlet的工作工程 Servlet是运行在Servlet容器(有时候也叫Servlet引擎,是web服务器和应用程序服务器的一部分,用于在发送的请求和响应之上提供网络服务,解码基于MIME的 ...

  3. 面试之jsp、Servlet相关知识——生命周期, 区别等

    1.servlet生命周期 所谓生命周期,指的是servlet容器如何创建servlet实例.分配其资源.调用其方法.并销毁其实例的整个过程. 阶段一: 实例化(就是创建servlet对象,调用构造器 ...

  4. servlet反射、生命周期、接口

    什么是Servlet Servlet是JavaWeb的三大组件之一,它属于动态资源.Servlet的作用是处理请求,服务器会把接收到的请求交给Servlet来处理,在Servlet中通常需要: l  ...

  5. Java Servlet(二):servlet配置及生命周期相关(jdk7+tomcat7+eclipse)

    该篇文章记录了Servlet配置相关用法及Servlet在Servlet容器中生命周期方法. Tomcat是一个Servlet容器: 1.Servlet容器管理了Servlet的整个生命周期,并调用s ...

  6. Servlet和JSP生命周期概述

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt374 Servlet生命周期分为三个阶段: 1,初始化阶段  调用init( ...

  7. servlet简介及生命周期

    Servlet 简介 Servlet 是什么? Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上 ...

  8. jsp当做第二个servlet request的生命周期 请求 响应 不管中间经历多少个servlet 只要最后一个serlvt执行后 则生命周期结束 request的域消失

    jsp当做第二个servlet  request的生命周期   请求 响应  不管中间经历多少个servlet 只要最后一个serlvt执行后 则生命周期结束  request的域消失

  9. java Web servlet简介及其生命周期

    Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,主要功能在于交互式地浏览和修改数据,生成动态Web内容. 我们可 ...

随机推荐

  1. c# Winform Invoke 的用法

    在Winform中线程更新UI线程 例如:Form中有一个DataGridView,我们使用Thread查询后,更新这个表格,如果在Thread中直接更新会报错. Thread th = new Th ...

  2. R语言读入数据库的中英名词互译测试并计分脚本(考试用)

    1. 分子生物学中英文.csv,输入文件,两列,以tab键分隔的txt文本,没有列名 2. 错误的名解.csv, 如果在测试中拼写错误,会写出到这个文件,可用这个容易犯错的名词进行新的测试 3. 注意 ...

  3. git命令别名(Alias)

    每次切换分支: git ckeckout branch_name 等命令费时又费力,git 别名配置起来: 别名配置: git config --global alias.ck ckeckout 其他 ...

  4. 【转载】.NET压缩/解压文件/夹组件

    转自:http://www.cnblogs.com/asxinyu/archive/2013/03/05/2943696.html 阅读目录 1.前言 2.关于压缩格式和算法的基础 3.几种常见的.N ...

  5. python+SQLAlchemy+爬虫

    python+SQLAlchemy+爬虫 前面分享了SQLAlchemy的知识,这次我共享一下学习用python开发爬虫再把爬出来的数据放到用SQLAlchemy的数据库上面的知识,当然我这个是带测试 ...

  6. 虚拟机桥接模式联网方法,Xshell的连接与使用

    1.虚拟机的编辑中的虚拟网络编译器,新建一个VMnet0,选择桥接模式,选择上网时的网卡. 2.虚拟机 -> 设置 -> 网络适配器,选择启动时连接,桥接模式,复制物理网络连接状态. 3. ...

  7. Oracle expdp数据泵导出,并在文件上附加上日期格式

    一.导出操作的计算机要安装Oracle Client(建议管理员版本) 二.在服务端创建目录 create directory dpdir as '目录'; 三.给目录赋权限 grant read,w ...

  8. Azure Web连接到Azure MySql Db

    这个问题折腾了好一会,简单记录一下. 两种方式: 输入"规则名称"."起始 IP"和"结束 IP",然后单击"保存". ...

  9. 【安富莱原创开源应用第1期】花式玩转网络摄像头之TCP上位机软件实现,高端大气上档次,速度2MB/S,华丽丽的界面效果

    说明:1.例子是两年前做的,一直没有顾上整理出来,今天特地整理出来,开源出来给大家玩.2.上位机是emWin模拟器开发的,大家估计很难猜到,所以你会emWin话的,就可以轻松制作上位机.做些通信和控制 ...

  10. 实战经验丨PHP反序列化漏洞总结

    又到了金三银四跳槽季,很多小伙伴都开始为面试做准备,今天小编就给大家分享一个网安常见的面试问题:PHP反序列化漏洞. 虽然PHP反序列化漏洞利用的条件比较苛刻,但是一旦被利用就会产生很严重的后果,所以 ...