Servlet生命周期总共由四个阶段:创建对象,初始化,服务,销毁

  • servlet类图

测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package com.gem.servlet;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
* @author zhang
* @date 2020/9/8 14:44
*/
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
public HelloServlet(){
System.out.println("这是构造方法");
}

@Override
public void init() throws ServletException {
super.init();
System.out.println("初始化方法");
}

@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("这是服务方法");
}

@Override
public void destroy() {
System.out.println("这是销毁方法");
super.destroy();
}
}

多次请求hello 构造方法和初始化方法只加载一次,服务方法加载多次

创建对象(不存在线程安全问题)

调用构造方法,默认情况下,当第一次访问到达服务器时,将调用构造方法创建对象,而且只创建一次(单例模式),我们可用通过load-on-startup来调节Servlet的创建时机

1
@WebServlet(urlPatterns = "/hello",loadOnStartup = 1)

整数表示服务器启动创建对象,值越小,约优先创建,0表示不在乎创建顺序,负数表示默认情况,表示当第一次到达创建

初始化(不存在线程安全问题)

调用完构造方法之后,紧接着调用init初始化方法。

init方法一般用于初始化数据,执行费时费力的重量级代码,

我们可以配置初始化参数,通过ServletConfig对象来获取初始化参数

1
@WebServlet(urlPatterns = "/hello",initParams = {@WebInitParam(name = "username",value = "root"),@WebInitParam(name = "password",value = "root")})

获取初始化参数

1
2
3
4
ServletConfig config = getServletConfig();
String username = config.getInitParameter("username");
String password = config.getInitParameter("password");
System.out.println(username + "-------" + password);

注意:Servlet顶级接口的init(ServletConfig config)方法时带参数的 。

我们可以发现HttpServlet的父类GenericServlet重写了带参数的init()方法,同时又提供了一个没有参数的init方法

在GenericServlet中,从servlet接口带来的init(ServletConfig config)对它进行重写时,如果忘了调用super.init(config)时,就会出现空指针异常,为了解决这样的

情况,GenericServlet中于是有了一个无参的init()方法,推荐大家重写init方法时,

重写无参的init()方法.

服务(非多线程安全)

如果有必要的话,需要进行线程同步,保证线程并发安全。

HttpServlet对service方法进行了大量的细分,例如doGet、doPost、doPut、doDelete…

销毁(不存在线程安全问题)

当卸载应用时,服务器会调用destory()方法,销毁当前Servlet的实例

注意:

如果当前Servlet没有提供服务,则可以被销毁。

如果当前Servlet实例正在提供服务,则调用destory()方法时,会等待一段时间,超时后销毁。

评论