目录
Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,具有独立于平台和协议的特性, 是运行在 Web 服务器或应用服务器上的程序,了解Servlet的生命周期对我们今后的学习有很大的帮助 。
一 . init() 方法
在 httpServlet 实例化之后被调用一次
tomcat 收到了 / hello 这样的路径请求 , 就会调用到 HelloServlet , 于是就需要先对 HelloServlet 进行实例化 (只进行一次) , 后续在收到 / hello 就不必重复实例化了 , 直接复用之前的 HelloServlet 实例即可 .
下面案例中经过多次请求, init 方法只执行一次即可 .
(1)init 方法被设计成只调用一次。它在第一次创建 Servlet 时被调用,在后续每次用户请求时不再调用。因此,它是用于一次性初始化,创建于用户第一次调用该 Servlet 的 URL 时,也可以指定 Servlet 在服务器第一次启动时被加载。
(2)当用户调用一个 Servlet 时,就会创建一个 Servlet 实例,每一个用户请求都会产生一个新的线程,适当的时候移交给 doGet 或 doPost 方法。
(3)init() 方法简单地创建或加载一些数据,这些数据将被用于 Servlet 的整个生命周期
如果要使init() 方法在服务器启动时就执行,则需要修改 web.xml 的配置 , 让tomcat 立即实例化 Servlet (增加一个特定的配置项即可)
二 . destroy() 方法
在长时间没有被调用或者是服务器关闭时,会调用destroy()方法来销毁Servlet对象。(终止阶段)
(1)destroy() 方法只会被调用一次,在 Servlet 生命周期结束时被调用。
(2)destroy() 方法可以让Servlet 关闭数据库连接、停止后台线程、把 Cookie 列表或点击计数器写入到磁盘,并执行其他类似的清理活动。
(3)在调用 destroy() 方法之后,servlet 对象被标记为垃圾回收。
@Override
public void destroy() {
System.out.println("destroy() 方法");
}
destroy() 方法能否执行到 ,如果是通过 smart tomcat 停止按钮 ,能够触发但是如果是直接杀进程 ,可能就开不及执行 destroy 就没了,因此不太推荐使用destroy()方法 。
三 . service () 方法
(1)service() 方法是执行实际任务的主要方法,处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端。
(2)每次服务器接收到一个 Servlet 请求时,服务器会产生一个新的线程并调用服务。
(3)service() 方法检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用 doGet、doPost、doPut,doDelete 等方法进行处理。
通过观察 service() 的源码可知 :
Servlet 接受和响应客户请求的过程 :
首先客户发送一个请求,Servlet是调用service()方法对请求进行响应的,通过源代码可见,service()方法中对请求的方式进行了匹配,选择调用doGet,doPost等这些方法,然后再进入对应的方法中调用逻辑层的方法,实现对客户的响应。由于在Servlet接口和GenericServlet中是没doGet,doPost等等这些方法的,HttpServlet中定义了这些方法,所以,我们每次定义一个Servlet的时候,都必须实现doGet或 doPost等这些方法。
当我们对service() 方法进行重写时 ,可以发现 doGet() 方法中的内容不再执行
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("service() 方法已被重写");
}
子类继承了 HttpServlet 父类之后 ,默认就会执行 service () 方法 ,进而执行 doxxx/方法 ,我们在实际开发过程中 , 很少会重写 init() / destroy() / service() 方法 , 经常重写的是 doxxx/方法
上述的 init() service() destroy() 方法 ,是HttpServlet 中比较重要的三个方法 , 共同构成了Servlet 的生命周期 。
根据上图 ,我们可以简要分析 servlet 的生命周期 。
四 . 生命周期过程
-
加载和实例化
当 Servlet 容器启动或者客户端向服务器发送请求时 , Servlet容器就会查找该内存中是否存在该Servlet 实例 , 如果存在 ,则直接读取该实例响应请求 , 如果不存在 ,就创建一个Servlet 实例。
-
初始化
实例化之后 ,Servlet 容器将调用的 init 方法进行初始化 (一些准备工作或者资源预加载工作)。
-
服务
初始化之后 ,Servlet 处于能响应请求的就绪状态 ,当接收到客户端请求时 , 调用service () 方法处理客户端请求 , HttpService() 的service() 方法就会根据不同的请求调用 不同的 doxx()方法。
-
销毁
当Servlet 容器关闭时 ,Servlet 实例也随时销毁 ,其间, Servlet 容器就会调用 Servlet 的destroy() 方法,对Servlet 对象标记为垃圾回收 , 停止后台线程 。
执行时序图 :