Servlet生命周期详解
Servlet生命周期概述servlet生命周期的四个过程1、实例化servlet对象我们的OOP(面向对象)思想中,总是先创建对象,通过对象调用成员,那么servlet如何实例化呢?设置对应servlet的优先级(loadOnStartup)2、初始化参数配置3、就绪状态4、销毁状态servlet生命周期简易总结概述servlet的生命周期:servlet在容器中开始实例化到实例销毁的整个过程s
Servlet生命周期
概述
servlet的生命周期:servlet在容器中开始实例化到实例销毁的整个过程
servlet生命周期的四个过程
1、实例化servlet对象
我们的OOP(面向对象)思想中,总是先创建对象,通过对象调用成员,那么servlet如何实例化呢?
- 第一种方式:通过配置文件web.xml进行实例化
public class ActionServlet extends HttpServlet {
//1、构造器
public ActionServlet(){
System.out.println("servlet对象实例化中.....");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<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-->
<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-->
<servlet>
<servlet-name>testServlet</servlet-name>
<servlet-class>org.softeem.controller.ActionServlet</servlet-class>
<!--设定当前servlet与容器加载时加载-->
<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-->
<servlet>
<servlet-name>testServlet</servlet-name>
<servlet-class>org.softeem.controller.ActionServlet</servlet-class>
<!--设定当前servlet与容器加载时加载-->
<load-on-startup>1</load-on-startup>
<!--配置初始化参数,可以同时配置多组-->
<!--1、配置编码-->
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<!--2、配置昵称-->
<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、就绪状态
service()方法是执行实际任务的主要方法,Web服务器将调用service方法处理客户端(浏览器)的请求,然后将格式化的数据响应给浏览器客户端。每当客户端向服务端发送一个请求时,服务端都会产生一个新的线程调用服务。service方法将会检测客户端发送给服务端的HTTP请求协议的类型,从而调用service方法中的 doGet、doPost、doPut、doDelete 等方法进行实际任务的逻辑处理,其中的执行流程图如下
单个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()就绪中...");
}
}
程序运行结果如下
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实例进行清除处理
详细请参考上面…
感谢大家的支持,我会继续提高相关技术…
更多推荐
所有评论(0)