• Servlet相关接口和Servlet的生命周期


    http://www.cnblogs.com/luotaoyeah/p/3860292.html

    Servlet相关接口和Servlet的生命周期

    创建一个Servlet类最直接的方式是实现javax.servlet.Servlet接口,Servlet接口的定义如下,其中定义了5个方法,Servlet的生命周期就是通过这几个方法体现的:
    复制代码

    1 public interface Servlet {
    2 public void init(ServletConfig config) throws ServletException;
    3
    4 public ServletConfig getServletConfig();
    5
    6 public void service(ServletRequest req, ServletResponse res)
    7 throws ServletException, IOException;
    8
    9 public String getServletInfo();
    10
    11 public void destroy();
    12 }

    复制代码

    1 . 加载和实例化

    首先定义一个DemoServlet实现Servlet接口,覆写接口中的方法,分别打印各自的方法名,在无参构造方法中也打印一句话:
    复制代码

    1 public class DemoServlet implements Servlet {
    2
    3 public DemoServlet() {
    4 System.out.println("constructor…");
    5 }
    6
    7 @Override
    8 public void destroy() {
    9 System.out.println("DemoServlet.destroy()");
    10 }
    11
    12 @Override
    13 public ServletConfig getServletConfig() {
    14 System.out.println("DemoServlet.getServletConfig()");
    15 return null;
    16 }
    17
    18 @Override
    19 public String getServletInfo() {
    20 System.out.println("DemoServlet.getServletInfo()");
    21 return null;
    22 }
    23
    24 @Override
    25 public void init(ServletConfig config) throws ServletException {
    26 System.out.println("DemoServlet.init()");
    27 }
    28
    29 @Override
    30 public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
    31 System.out.println("DemoServlet.service()");
    32 }
    33
    34 }

    复制代码

    Servlet要被容器所管理,需要在web.xml中进行配置:
    复制代码

    1 <servlet>
    2 <servlet-name>demo</servlet-name>
    3 <servlet-class>servlet.DemoServlet</servlet-classs>
    4 </servlet>
    5 <servlet-mapping>
    6 <servlet-name>demo</servlet-name>
    7 <url-pattern>/demo</url-pattern>
    8 </servlet-mapping>

    复制代码

    启动服务器,通过“http://localhost:8080/${contextpath}/demo”请求该Servlet,控制台打印输出如下:

    刷新页面,再次请求该Servlet,控制台打印如下,可以看到,第二次请求只执行了service(ServletRequest req, ServletResponse res)方法:

    当服务器接收到请求时,会通过web.xml中的配置寻找匹配的Servlet,找不到则报404错误;找到之后,根据配置的Servlet类的全限定名查找服务器中是否已经存在该Servlet类的实例,若存在则直接使用它来处理本次请求(上面的第二次请求,该Servlet实例已经存在,直接调用该实例的service(ServletRequest req, ServletResponse res)方法。);若不存在,则根据全限定名通过反射创建实例(调用公共无参的构造方法)。从这里可以看出,若没有提供可访问的无参构造方法,会报错:

    1 //提供有参构造方法,覆盖了默认的无参构造方法
    2 public DemoServlet(String s) {
    3 System.out.println("constructor…");
    4 }

    服务器通过反射调用Class.newInstance()方法创建实例,找不到可访问的无参构造方法,自然会报错。

    2 . 初始化

    从上面可以看到,在第一次请求,创建Servlet实例的时候,调用了init(ServletConfig config)方法完成初始化。初始化只会在创建实例的时候进行,以后的请求不会再进行初始化,直接调用service()方法处理请求。服务器在进行Servlet初始化的时候,会首先准备一个ServletConfig对象,通过该对象可以从应用程序的配置信息中获取初始化的参数信息;数据库连接的建立等任务通常也是在初始化阶段完成。

    ServletConfig接口中定义了4个方法,用来获取初始化参数信息:
    复制代码

    1 public interface ServletConfig {
    2 //获取Servlet的名字,即在web.xml中<servlet-name>demo</servlet-name>节点配置的信息
    3 public String getServletName();
    4
    5 //获取Servlet上下文对象
    6 public ServletContext getServletContext();
    7
    8 //根据参数名获取初始化参数值
    9 public String getInitParameter(String name);
    10
    11 //获取所有初始化参数名
    12 public Enumeration<String> getInitParameterNames();
    13 }

    复制代码

    初始化参数可以在web.xml中配置:
    复制代码

    1 <servlet>
    2 <servlet-name>demo</servlet-name>
    3 <servlet-class>servlet.DemoServlet</servlet-class>
    4 <init-param>
    5 <param-name>username</param-name>
    6 <param-value>admin</param-value>
    7 </init-param>
    8 </servlet>
    9 <servlet-mapping>
    10 <servlet-name>demo</servlet-name>
    11 <url-pattern>/demo</url-pattern>
    12 </servlet-mapping>

    复制代码

    注意:如果在web.xml中配置了<load-on-startup>1</load-on-startup>,该Servlet会在服务器启动的时候就完成实例的创建和初始化,而不是在第一次请求的时候:
    复制代码

    1 <servlet>
    2 <servlet-name>demo</servlet-name>
    3 <servlet-class>servlet.DemoServlet</servlet-class>
    4 <load-on-startup>1</load-on-startup>
    5 </servlet>
    6 <servlet-mapping>
    7 <servlet-name>demo</servlet-name>
    8 <url-pattern>/demo</url-pattern>
    9 </servlet-mapping>

    复制代码

    3 . 处理请求

    服务器调用service(ServletRequest req, ServletResponse res)方法来处理请求。处理请求之前,init()方法必须成功执行。服务器在调用service(ServletRequest req, ServletResponse res)方法之前,已经准备好了ServletRequest对象和ServletResponse对象,并作为参数传给service(ServletRequest req, ServletResponse res)方法。

    ServletRequest接口和ServletResponse接口中定义了用来处理请求和响应的相关方法:

    4 . 销毁

    当容器检测到一个Servlet实例应该从服务中被移除的时候,容器就会调用实例的destroy()方法,以便让该实例可以释放它所使用的资源,保存数据到持久存储设备中。当需要释放内存或者容器关闭时,容器就会调用Servlet实例的destroy()方法。在destroy()方法调用之后,容器会释放这个Servlet实例,该实例随后会被Java的垃圾收集器所回收。如果再次需要这个Servlet处理请求,Servlet容器会创建一个新的Servlet实例。

    destroy()方法跟init()方法一样,在Servlet的生命周期中只会被执行一次,但destroy()方法不会总是被执行,如服务器被异常终止时,destroy()方法就不能被执行。

  • 相关阅读:
    NeuChar 平台使用及开发教程(六):成为开发者
    NeuChar 平台使用及开发教程(五):使用 NeuChar 的关键字回复服务
    NeuChar 平台使用及开发教程(四):使用 NeuChar 的素材服务
    NeuChar 平台使用及开发教程(三):使用 NeuChar 的菜单服务
    NeuChar 平台使用及开发教程(二):设置平台账号
    NeuChar 平台使用及开发教程(一):开始使用 NeuChar
    Senparc.Weixin.TenPay 正式发布
    ubuntu 16.04 安装teamviewer
    如何学会快速调用API
    markdown的使用
  • 原文地址:https://www.cnblogs.com/jukan/p/5259110.html
Copyright © 2020-2023  润新知