Servlet生命周期
概述
servlet的生命周期:servlet在容器中开始实例化到实例销毁的整个过程
servlet生命周期的四个过程
1、实例化servlet对象
我们的OOP(面向对象)思想中,总是先创建对象,通过对象调用成员,那么servlet如何实例化呢?
- 第一种方式:通过配置文件web.xml进行实例化
public class ActionServlet extends HttpServlet {
//1、构造器 public ActionServlet(){
System.out.println("servlet对象实例化中....."); } }
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0">
<servlet> <servlet-name>testServlet
servlet-name> <servlet-class>org.softeem.controller.ActionServlet
servlet-class>
servlet> <servlet-mapping> <servlet-name>testServlet
servlet-name> <url-pattern>/friend_demo/action
url-pattern>
servlet-mapping>
web-app>
- 第二种方式:注解
//注解方式,效果等同于web.xml中的配置 @WebServlet("/friend_demo/action") public class ActionServlet extends HttpServlet {
//1、构造器 public ActionServlet(){
System.out.println("servlet对象实例化中....."); } }
- 通过以上两种方式中的一种,此时运行tomcat会出现如下结果
23-Jan-2021 21:52:28.552 信息 [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-8009"] 23-Jan-2021 21:52:28.554 信息 [main] org.apache.catalina.startup.Catalina.start Server startup in 39 ms Connected to server [2021-01-23 09:52:29,482] Artifact ZhenaiDemo:war exploded: Artifact is being deployed, please wait... 23-Jan-2021 21:52:29.779 警告 [RMI TCP Connection(3)-127.0.0.1] org.apache.tomcat.util.descriptor.web.WebXml.setVersion Unknown version string [4.0]. Default version will be used. 23-Jan-2021 21:52:30.540 信息 [RMI TCP Connection(3)-127.0.0.1] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time. servlet对象实例化中.....
- 通过上面的运行结果可以发现,确实调用了ActionServlet 类中的无参构造器。但是,出现该结果是在我们在浏览器客户端中输入了当前servlet对应的 /friend_demo/action 请求后才在控制台中输出 “servlet对象实例化中…”,由此可以发现只有当我们在使用对应的servlet时才会进行对象的创建。有时我们需要某个servlet随着容器加载时就创建servlet对象,而不是在使用时才创建。这是就可以通过设定servlet对应的优先级来决定servlet实例化的时机
设置对应servlet的优先级(loadOnStartup)
设定servlet优先级可以使用loadOnStartup属性,对应的属性值越小优先级别越高。当我们需要servlet与tomcat容器一起加载时而被实例化,即将loadOnStartup属性值设定为1,设定的方式有两种
- 配置文件方式
<servlet> <servlet-name>testServlet
servlet-name> <servlet-class>org.softeem.controller.ActionServlet
servlet-class>
<load-on-startup>1
load-on-startup>
servlet> <servlet-mapping> <servlet-name>testServlet
servlet-name> <url-pattern>/friend_demo/action
url-pattern>
servlet-mapping>
- 注解方式
注意:若同时设定请求协议与优先级时,需要将协议赋值给value属性,且中间使用逗号隔开,如下
@WebServlet(value="/friend_demo/action",loadOnStartup = 1) public class ActionServlet extends HttpServlet {
//1、构造器 public ActionServlet(){
System.out.println("servlet对象实例化中....."); } }
2、初始化参数配置
servlet实例化后就会调用init方法,被设计为只能调用一次,且是在进行第一次实例化servlet对象时调用。当用户在调用servlet时,就会创建一个servlet实例,每一次在客户端发送的请求servlet就会产生一个新的线程,从而调用对应的doGet 或 doPost 方法。init方法的作用在于初始化一些配置参数(比如编码设置),并写这些参数将被贯穿整个servlet生命周期。配置参数的参数有两种,如下
- 通过配置文件web.xml方式配置
<servlet> <servlet-name>testServlet
servlet-name> <servlet-class>org.softeem.controller.ActionServlet
servlet-class>
<load-on-startup>1
load-on-startup>
<init-param> <param-name>encoding
param-name> <param-value>utf-8
param-value>
init-param>
<init-param> <param-name>userName
param-name> <param-value>上进的小仓鼠
param-value>
init-param>
servlet> <servlet-mapping> <servlet-name>testServlet
servlet-name> <url-pattern>/friend_demo/action
url-pattern>
servlet-mapping>
@WebServlet(value="/friend_demo/action",loadOnStartup = 1) public class ActionServlet extends HttpServlet {
//1、构造器 public ActionServlet(){
System.out.println("servlet对象实例化中....."); } //2、初始化 @Override public void init(ServletConfig config) throws ServletException {
System.out.println("servlet初始化中......"); //获取配置的参数值 String encoding = config.getInitParameter("encoding"); String userName = config.getInitParameter("userName"); System.out.println(encoding + "," + userName); }
- 通过注解方式配
@WebServlet(value="/friend_demo/action",loadOnStartup = 1, initParams = {
@WebInitParam(name="encoding",value = "utf-8"), @WebInitParam(name="userName",value = "上进的小仓鼠") } ) public class ActionServlet extends HttpServlet {
//1、构造器 public ActionServlet(){
System.out.println("servlet对象实例化中....."); } //2、初始化 @Override public void init(ServletConfig config) throws ServletException {
System.out.println("servlet初始化中......"); //获取配置的参数值 String encoding = config.getInitParameter("encoding"); String userName = config.getInitParameter("userName"); System.out.println(encoding + "," + userName); } }
配置完参数运行结果如下:
23-Jan-2021 22:42:05.584 信息 [main] org.apache.catalina.startup.Catalina.start Server startup in 29 ms Connected to server [2021-01-23 10:42:05,899] Artifact ZhenaiDemo:war exploded: Artifact is being deployed, please wait... 23-Jan-2021 22:42:06.062 警告 [RMI TCP Connection(3)-127.0.0.1] org.apache.tomcat.util.descriptor.web.WebXml.setVersion Unknown version string [4.0]. Default version will be used. 23-Jan-2021 22:42:06.657 信息 [RMI TCP Connection(3)-127.0.0.1] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time. servlet对象实例化中..... servlet初始化中...... utf-8,上进的小仓鼠
3、就绪状态
- 案例代码如下
@WebServlet(value="/friend_demo/action",loadOnStartup = 1, initParams = {
@WebInitParam(name="encoding",value = "utf-8"), @WebInitParam(name="userName",value = "上进的小仓鼠") } ) public class ActionServlet extends HttpServlet {
//1、构造器 public ActionServlet(){
System.out.println("servlet对象实例化中....."); } //2、初始化 @Override public void init(ServletConfig config) throws ServletException {
System.out.println("servlet初始化中......"); //获取配置的参数值 String encoding = config.getInitParameter("encoding"); String userName = config.getInitParameter("userName"); System.out.println(encoding + "," + userName); } //3、就绪状态 @Override public void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
System.out.println("servlet:service()就绪中..."); } }
程序运行结果如下
23-Jan-2021 22:42:15.575 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory D:\apache\apache-tomcat-8.0.45\webapps\manager 23-Jan-2021 22:42:15.594 信息 [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory D:\apache\apache-tomcat-8.0.45\webapps\manager has finished in 18 ms [2021-01-23 10:54:32,996] Artifact ZhenaiDemo:war exploded: Artifact is being deployed, please wait... servlet实例销毁中.... servlet对象实例化中..... servlet初始化中...... utf-8,小仓鼠 [2021-01-23 10:54:34,124] Artifact ZhenaiDemo:war exploded: Artifact is deployed successfully [2021-01-23 10:54:34,124] Artifact ZhenaiDemo:war exploded: Deploy took 1,128 milliseconds servlet:service()就绪中...
4、销毁状态
servlet生命周期结束时将会调用destroy()方法,并且只会调用一次。destroy方法可以让我们的servlet关闭数据库连接,把后台线程关闭,清楚Cookie数据等。当调用了destroy()方法后,当前servlet实例将会被标记为回收垃圾,会对servlet实例进行清除,案例代码如下
@WebServlet(value="/friend_demo/action",loadOnStartup = 1, initParams = {
@WebInitParam(name="encoding",value = "utf-8"), @WebInitParam(name="userName",value = "上进小仓鼠") } ) public class ActionServlet extends HttpServlet {
//1、构造器 public ActionServlet(){
System.out.println("servlet对象实例化中....."); } //2、初始化 @Override public void init(ServletConfig config) throws ServletException {
System.out.println("servlet初始化中......"); //获取配置的参数值 String encoding = config.getInitParameter("encoding"); String userName= config.getInitParameter("userName"); System.out.println(encoding + "," + userName); } //3、就绪状态 @Override public void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
System.out.println("servlet:service()就绪中..."); } //4、销毁状态 @Override public void destroy() {
System.out.println("servlet实例销毁中...."); } }
执行程序后的运行效果
[2021-01-23 10:54:32,996] Artifact ZhenaiDemo:war exploded: Artifact is being deployed, please wait... servlet实例销毁中.... servlet对象实例化中..... servlet初始化中...... utf-8,小仓鼠 [2021-01-23 10:54:34,124] Artifact ZhenaiDemo:war exploded: Artifact is deployed successfully [2021-01-23 10:54:34,124] Artifact ZhenaiDemo:war exploded: Deploy took 1,128 milliseconds servlet:service()就绪中... [2021-01-23 11:06:03,372] Artifact ZhenaiDemo:war exploded: Artifact is being deployed, please wait... servlet实例销毁中....
servlet生命周期总结
- 实例化:servlet容器创建servlet对象。默认创建servlet实例的时机:当我们发送servlet对应的请求时(在使用时创建)。类似单例模式中的懒加载方式。希望容器一旦启动,就自动创建servlet实例通过load-on-startup=1设置,正数数值越低优先级别越高,优先实例化
- 初始化:servlet实例一旦创建,就开始初始化一些参数配置,我们可以做一些参数配置,比如编码,可以在web.xml或注解中配置
- 就绪状态:当发送对应的servlet请求时,会调用service()方法,注意此时不会重新创建servlet实例,也不会调用init()方法
- 销毁状态:调用了destroy()方法后,当前servlet实例将会被标记为回收垃圾,会对servlet实例进行清除处理
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/216530.html原文链接:https://javaforall.net
