Servlet的生命周期

本文详细介绍了Servlet的生命周期,包括Servlet的实例化、初始化、服务处理请求及销毁四个阶段。在实例化时,根据请求路径创建Servlet实例;初始化阶段调用init()方法,仅执行一次;service()方法处理客户端请求,根据请求方式调用doGet()或doPost();销毁时调用destroy()方法进行资源清理。理解Servlet生命周期对于有效管理Servlet资源至关重要。
摘要由CSDN通过智能技术生成

Servlet的生命周期从创建到销毁可分为如下四个过程:

  1. Servlet实例化;
  2. 调用init()方法初始化;
  3. 调用service()方法来处理客户端的请求;
  4. 调用destory()方法销毁;

接下来我们详细了解下Servlet生命周期的四个过程。

一、实例化

        根据Servlet请求的路径,查找Servlet的实例,如果实例不存在,则通过调用构造方法完成Servlet实例的创建。Servlet的请求路径可通过配置web.xml文件或者注解的方式,一般都使用注解,比较方便例如(@WebServlet("/demo.do"));

二、初始化

        通过Servlet实例调用init()方法初始化,init()方法只能调用一次,在第一次创建Servlet时被调用,在之后每次请求时则不再调用。在init()方法里面创建的数据,可以被用于Servlet的整个生命周期。

代码举例:

package com.my.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("/demo.do")
public class DemoServlet extends HttpServlet {
	
	//1.实例化
	//构造方法
	public DemoServlet() {
		System.out.println("DemoServlet被实例化!");
	}

	//2.初始化
	//重写HttpServlet(父类)的init()方法初始化
	//通过创建的实例自动调用init()方法
	@Override
	public void init() throws ServletException {
		System.out.println("DemoServlet被初始化!");
	}
	
	//3.服务
	//通过实例调用父类的Service()方法
	//Service()方法会根据请求方式的不同(GET或POST)
	//调用子类重写的doGet或doPost方法
	//如果子类没有重写,则调用父类的方法(响应405)
	// 根据响应方式的不同,需要调用不同的请求方法
	
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("service方法被调用!");
	}


3be296b5ef354450ae8014b62625dca7.png

 

        当浏览器请求该Servlet路径时,先通过构造方法创建实例,在通过实例调用init()方法进行初始化,这里浏览器发起了6次请求,可以发现init()方法只被调用了一次。

 

三、服务

        service()方法是执行实际任务的主要方法。Servlet容器调用service()方法来处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端。

        每次服务器接收到一个Servlet请求时,实例化Servlet后,通过实例调用父类的Service()方法,Service()方法会根据请求方式的不同(GET或POST),调用子类重写的doGet()doPost()方法,如果子类没有重写,则调用父类的方法doGet()或doPost()方法,而父类的doGet()和doPost()方法响应一个405错误页面,所以一般都会重写doGet()和doPost()方法。当然,你也可以重写父类的Service方法,但没有实际意义。

父类HttpServlet中源码如下:

aaf1e8dc795a47e380ae428c1be998c9.png 

 72266c0bde684b0b81432bda6941d9c2.png

 5bc536f850b84799a9a79c0192c04c02.png

 819af3926dd646818ec4356b05d31a1b.png

 根据响应方式的不同,需要调用不同的请求方法

代码演示:

package com.my.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("/demo.do")
public class DemoServlet extends HttpServlet {
	
	//1.实例化
	//构造方法
	public DemoServlet() {
		System.out.println("DemoServlet被实例化!");
	}

	//2.初始化
	//重写HttpServlet(父类)的init()方法初始化
	//通过创建的实例自动调用init()方法
	@Override
	public void init() throws ServletException {
		System.out.println("DemoServlet被初始化!");
	}
	
	//3.服务
	//通过实例调用父类的Service()方法
	//Service()方法会根据请求方式的不同(GET或POST)
	//调用子类重写的doGet或doPost方法
	//如果子类没有重写,则调用父类的方法(响应405)
	// 根据响应方式的不同,需要调用不同的请求方法
	
	
//	@Override
//	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//		System.out.println("doGet方法被调用!");
//	}
	
//	@Override
//	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//		System.out.println("doPost方法被调用!");
//	}

        子类中没有重写父类的doGet()和doPost()方法时,收到来自浏览器的GET请求,则会出现405错误页面。405状态码:代表请求的方式服务器不提供支持

36601db2213d4cd2bd30b08cdbbe3b4e.png

 b8f4686e25034faaa8b858f7222925ad.png

         子类重写doGet()方法,收到来自浏览器的GET请求,则会通过父类service()方法进行逻辑判断后调用子类重写的doGet()方法。这里我将结果输出至控制台。

        9eb3729a7fbd4f029dd602d4eef761ce.png

 

四、销毁

        服务器关闭或重启的时候,会调用Servlet实例的destroy()销毁所有的Servlet实例。destroy()方法也只会被调用一次,在Servlet生命周期结束时调用。destroy()方法会将Servlet关闭数据库连接、停止后台线程、把Cookie列表或点击计数器写入到磁盘,并执行其他类似的清理活动。在调用destroy()方法之后,Servlet对象会被标记为垃圾回收。

代码示例:

package com.my.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("/demo.do")
public class DemoServlet extends HttpServlet {
	
	//1.实例化
	//构造方法
	public DemoServlet() {
		System.out.println("DemoServlet被实例化!");
	}

	//2.初始化
	//重写HttpServlet(父类)的init()方法初始化
	//通过创建的实例自动调用init()方法
	@Override
	public void init() throws ServletException {
		System.out.println("DemoServlet被初始化!");
	}
	
	//3.服务
	//通过实例调用父类的Service()方法
	//Service()方法会根据请求方式的不同(GET或POST)
	//调用子类重写的doGet或doPost方法
	//如果子类没有重写,则调用父类的方法(响应405)
	// 根据响应方式的不同,需要调用不同的请求方法
	
//	@Override
//	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//		System.out.println("service方法被调用!");
//	}

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		System.out.println("doGet方法被调用!");
	}
	
//	@Override
//	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//		System.out.println("doPost方法被调用!");
//	}
	
	//销毁
	//重写父类的destroy()方法
	@Override
	public void destroy() {
		System.out.println("实例对象已被销毁!");
	}

}

        通过浏览器请求Servlet路径发起请求,这里我发送了三次,最后关闭tomcat服务器。

运行结果

a5554eb9faa24ac4a6c189e40f0f468e.png

 


总结:

        当用调用一个Servlet时,就会创建一个Servlet实例,通过实例调用init()方法初始化,可以将Servlet中一直用到的资源放在init()方法中。当客户端(浏览器)请求Servlet路径发起请求,通过请求方式的不同,执行doGet()或doPost()方法,子类中重写doGet()或doPost()方法请求和响应给客户端浏览器。当服务器关闭或重启时,通过实例调用distroy()方法销毁所有Servlet实例,Servlet的生命周期到此就结束了。

 

  • 8
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值