Servlet的生命周期

一、了解Servlet

        Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,具有独立于平台和协议的特性, 是运行在 Web 服务器或应用服务器上的程序。和JDBC一样,Servlet同样是作为JavaEE规范的一项技术、接口、规范,他不能直接和客户端进行交互而是部署在一个容器中,像我们熟知的Tomcat容器,由这个容器来实现Servlet的接口,从而能和客户端进行交互。它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。主要功能在于收集来自网页表单的用户输入交互式地浏览和生成数据还可以生成动态Web内容

二、Servlet的生命周期

        在通过一个URL路径发起对一个Servlet请求的过程中,其本质是在调用执行Servlet实例的doXXX()方法。该Servlet实例创建和使用的过程,被称为Servlet的生命周期。整个生命周期包括:实例化、初始化、服务、销毁。

1. 加载和实例化

        从JavaSE的角度出发,我们如果想要获取一个对象的实例,有2种方法,一种是构造方法,另一种是反射,但是反射的本质还是调用构造方法,所以我们想要获取一个Servlet的实例对象,主要是通过他的构造方法。那么我们再回到Servlet,Servlet容器负责加载和实例化Servlet。当Servlet容器启动时,或者在容器检测到需要这个Servlet来响应第一个请求时,它必须要知道所需的Servlet类在什么位置,通过类加载器加载Servlet类,成功加载后,容器通过反射的形式,调用无参构造方法来创建Servlet的实例。

2.初始化

        在Servlet实例化之后,容器将调用Servlet的init()方法初始化这个对象。比如说,我们想要连接数据库,那么必然要与数据库建立连接,如果每调用一次Servlet就需要建立一次数据库连接的话,这对服务器端的压力是非常大的,所以我们只需要在创建该Servlet对象后,只建立一次与数据库的连接,而初始化的目的就是为了让Servlet对象在处理客户端请求前完成一些初始化的工作,而对于每一个Servlet实例,init()方法只被调用一次。

3.服务

        在完成Servlet对象的创建以及初始化后,就该到了我们想要使用Servlet去干什么的阶段了,而这个阶段主要是调用service()方法来处理来自客户端的请求,目前经常使用的请求主要是GET和POST,当然也有其他的,比如HEAD、PUT等,那么在service方法中主要就是处理这些请求,比如doGet()、doPost()等,而这些方法的实现在HttpServlet父类中,都是返回给一个405状态码的响应,表示服务器不支持该方式的请求。

        如果想要访问我们自定义的Servlet,到服务阶段:

        如果子类没有重写service()方法,则调用HttpServlet父类的service()方法,在父类的该方法中进行请求方式的判断,如果是GET请求,则调用doGet()方法;如果是POST请求,则调用doPost()方法; 如果子类重写doXXX()方法,则调用子类重写后的doXXX()方法;如果子类没有重写doXXX()方法,则调用父类的doXXX()方法,在父类的方法实现中,返回一个405状态码的错误页面。

        如果子类重写了service()方法,那么只执行子类的service()方法,doXXX()方法也不再执行。

4.销毁

        当服务器停止或者重启时,也就代表一个Servlet的生命周期即将结束,调用实例的destroy()方法实现销毁,自此,Servlet会作为垃圾等待回收。

Servlet生命周期代码实现

package com.fulian.web.servlet;

import java.io.IOException;

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

@WebServlet("/home.do")
public class HomeServlet extends HttpServlet {
	
	// 1.实例化
	// 构造方法
	public HomeServlet() {
		System.out.println("1.HomeServlet实例被创建");
	}
	
	// 2.初始化
	// 重写HttpServlet父类的init()方法
	// 通过实例自动调用init()方法
	@Override
	public void init() throws ServletException {
		System.out.println("2.HomeServlet实例初始化");
	}
	
	// 3.服务
	// 通过实例调用HttpServlet父类的service()方法
	// service()方法中,会根据请求方式(get或post)的不同
	// 调用子类重写的doGet()或doPost()
	// 如果子类没用重写,则响应405
	
	// 根据请求方式的不同,需要调用不同的请求方法
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("doGet被单机了!" + this.hashCode());
		String method = req.getMethod();
		System.out.println("请求方式:" + method);
		
		System.out.println(req.getRemoteAddr());
		
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("doPost被单机了!");
	}
	
	// 4.销毁
	@Override
	public void destroy() {
		System.out.println("4.HomeServlet实例被销毁");
	}
	
	
}

当发起多次对home.do的请求后,可以看到:

         当服务器启动,发起对home.do的请求时,其生命周期开始,完成实例化、初始化和doGet()方法的调用,当第二次访问时,不再进行实例化和初始化,从hashcode可以看出,两次访问都是同一个HomeServlet实例对象,当服务器重启时,完成对HomeServlet的销毁。再次对home.do发起请求,创建并实例化一个新的HomeServlet实例对象,开始新的生命周期。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

仙草不加料

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值