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

原文链接: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. MongoDB 学习使用

    博客教程: https://jingyan.baidu.com/article/dca1fa6f0428a4f1a440522e.html

  2. 上传插件webupload之调用拍照兼容问题

    在项目中,移动端用到了webupload插件来实现上传功能(我觉得这个插件挺好用的,所以无论pc还是移动端我都使用了这个插件来做上传功能) 在移动端要调起拍照功能,实现上传,须得在webuploade ...

  3. java课程之团队开发冲刺阶段1.2

    一.总结昨天进度 1.三个任务都已经实现 2.使用时间:四个小时左右 二.遇到的困难 1.对Android原生的侧拉任务栏不了解,导致使用的时候出现了一部分问题 三.今天任务规划 1.对之前的程序重新 ...

  4. dedecms给图片加水印覆盖整张图片

    位置: /include/image.class.php $wmwidth = $imagewidth - $logowidth; $wmheight = $imageheight - $logohe ...

  5. Linux 搭建 Nginx+PHP-FPM环境

    安装PHP.Nginx和PHP-FPM sudo apt-get install php sudo apt-get install nginx sudo apt-get install php7-fp ...

  6. Bypass_Disable_functions_Shell

    Bypass_Disable_functions_Shell https://github.com/l3m0n/Bypass_Disable_functions_Shell 一个各种方式突破Disab ...

  7. 解决idea中 mvn项目导了包找不到包的问题

    ----------------------------------------分割线--------------------------------------------------------- ...

  8. 在 ubuntu 中愉快的安装 Jenkins

    这篇文章详细的记录了在 ubuntu 中安装 Jenkins 的一步又一步,因为找了很多 Linux 下安装 Jenkins 的教程,不是很满意 所以决定自己写一篇以备后用(终于让我找到了Java 不 ...

  9. Java synchronized和 Lock 的区别与用法

    在分布式开发中,锁是线程控制的重要途径.Java为此也提供了2种锁机制,synchronized和lock.做为Java爱好者,自然少不了对比一下这2种机制,也能从中学到些分布式开发需要注意的地方.  ...

  10. 通信统计接口字段填充内容shell脚本

    现在通信行业上班,最麻烦的就是计算各个协议接口字段填充的内容是否正确.经历了小白似的一个个字段统计在到单个接口所有字段统计,然后到现在的多个接口一次统计.在大大节省了时间的同时,让自己有更充足的时间来 ...