• JaveWeb学习之Servlet(一):Servlet生命周期和加载机制


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

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

    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()执行销毁...
      

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

  • 相关阅读:
    二分图最大匹配的K&#246;nig定理及其证明
    HDOJ 2389 Rain on your Parade
    HDOJ 1083 Courses
    HDOJ 2063 过山车
    POJ 1469 COURSES
    UESTC 1817 Complete Building the Houses
    POJ 3464 ACM Computer Factory
    POJ 1459 Power Network
    HDOJ 1532 Drainage Ditches
    HDU 1017 A Mathematical Curiosity
  • 原文地址:https://www.cnblogs.com/guitu18/p/9350262.html
Copyright © 2020-2023  润新知