Servlet的生命周期可以定义为从其被创建到其被销毁的整个流程,下面是Servlet生命的常规线路:
- 容器调用init()方法进行Servlet的初始化
- Servlet调用service()方法去处理客户端的请求
- 容器调用destroy()方法将Servlet销毁
- 最后,Servlet被JVM的GC线程当作垃圾处理掉
init()方法:
init()方法只会在创建Servlet时被调用一次,不管有多少用户请求。通常情况下,Servlet在容器第一次接收到用户请求时被创建,但也可以通过load-on-startup指定Servlet在容器启动时将其加载。
当用户调用Servlet时,容器中的每一个Servlet都是以单例模式对外提供服务的,只是会对每一个用户分配一个线程。init()方法内部通常会加载一些在Servlet的生命周期中会用到的数据。
init()方法的定义如下所示:
public void init() throws ServletException { // Initialization code... }
service()方法:
service()方法是Servlet对外提供服务的主方法。Servlet容器会调用该方法处理来自客户端的请求以及将格式化的返回结果返回给客户端。
每当Servlet容器接收到来自客户端的请求时,它会分配一个新的线程并且调用service()方法,然后由service()方法去检测客户端的请求类型,是GET还是POST还是DELETE还是PUT等等,然后在service()方法的内部会依据请求的类型相应的调用doGet,doPost,doDelete,doPut方法。
service()方法的声明如下:
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException{ }
由上可知,针对service()方法,开发人员不需要做任何调整,但是却需要依据请求类型重写被其调用的doGet或doPost方法。doGet和doPost是使用最频繁的两个方法,下面是它们的定义:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Servlet code }
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Servlet code }
通过URL的普通请求以及未指定METHOD的HTML表单会产生GET模式的请求,因此该类请求会被doGet方法处理;而指定了METHOD的HTML表单会产生POST模式的请求,此时会被doPost方法处理。
destroy()方法:
destroy()方法只会在Servlet的生命到达尽头时被调用一次,该方法会给Servlet去做一些最后扫尾的机会,比如关闭数据库连接,停止后台线程,写cookie列表等。当destroy方法被调用之后,Servlet对象会被标记来“垃圾”,由GC处理掉。destroy()方法的定义如下:
public void destroy() { // Finalization code... }
架构图:
上图描述了Servlet的生命周期图:
- 首先,面向web服务器的HTTP请求会被委托给Servlet容器
- 其次,servlet容器在调用service()方法之前会先加载servlet
- 最后,servlet容器会以多线程的方式处理多用户的请求,每个线程都会执行单例的servlet的service()方法。
/******************************外星人乔丹拍板时间******************************/
Servlet的生命,始于被创建时的init()方法,止于完成使命之后的destroy()方法,
生命只会开始一次,即Init() only once,生命也只会终止一次,即destroy() only once,
在生命的浪潮中,这个伟人会提供多次服务,即service() a lot of times
Servlet(二)生命周期