Servlet的生命周期主要有四个阶段:加载、初始化、执行、清除。
Servlet的载入指的是容器将Servlet类别加载JVM并实例化,这个时候Servlet对象还不算具备Servlet该有的功能,只能说是一个纯綷的Java对象,加载Servlet的时机有三种可能:
若要求在服务器启动时加载Servlet,可以在web.xml的<servlet>定义时,加入<load-on- startup>标签,例如:
web.xml... <servlet> <servlet-name>Servletname1</servlet-name> <servlet-class>demo.servlet.SomeServlet1</servlet-class> <load-on-startup>10</load-on-startup> </servlet> <servlet> <servlet-name>Servletname2</servlet-name> <servlet-class>demo.servlet.SomeServlet2</servlet-class> <load-on-startup>20</load-on-startup> </servlet> <servlet> <servlet-name>Servletname3</servlet-name> <servlet-class>demo.servlet.SomeServlet3</servlet-class> <load-on-startup>30</load-on-startup> </servlet> <servlet> <servlet-name>Servletname4</servlet-name> <servlet-class>demo.servlet.SomeServlet4</servlet-class> <load-on-startup/> </servlet> ...
<load-on-startup>卷标设定的是加载时的顺序值,数值越小就越先加载。
在Servlet类别被容器加载并实例化之后,会进行初始化的动作,此时init()方法会被呼叫执行,init()方法传入一个 ServletConfig型态的对象,表示与Servlet相关的环境对象,web.xml中的一些设定信息也包括在这个对象当中,在初始化之后, Servlet对象才称的上具备Servlet功能:
public void init(ServletConfig config) throws ServletException
ServletConfig的使用您并不陌生,在JSP的隐含对象 config 就是对应于ServletConfig,您可以用它来取得设定于web.xml中的初始参数(即使用config.getInitParameter ()):
web.xml... <servlet> ... <init-param> <param-name>parameter</param-name> <param-value>value</param-value> </init-param> ... </servlet> ...
您也可以使用无参数的init()方法,在Servlet 2.1之后,容器会呼叫有参数的init()方法,在执行完毕后再呼叫无参数的init()方法:
public void init() throws ServletException
通常在重新定义init()方法时,会这么撰写:
public void init(ServletConfig config) throws ServletException { super.init(config); // ..... }
这是了兼具Servlet 2.0之前的兼容,确保父类别GenericServlet会呼叫无参数的init()方法:
public class GenericServlet implements Servlet, ServletConfig { ServletConfig _config = null; public void init(ServletConfig) throws ServletException { _config = config; log("init classed"); init(); } .... }
Servlet的初始化可以用于一些资源的预先加载,例如开启数据库联机,避免在使用者第一次请求网页时才开启数据库联机,以免使用者必须花费时间等待联机的完成。
Servlet在加载之后会一直存在于服务器的内存中,直到服务器关闭或是要求清除Servlet时,这可以避免对象生成时所需的时间与资源负担,并可 实现一些信息的持续性(persistence),每一个使用者请求Servlet时,容器会产生一个执行线来存取Servlet,也因而在设计 Servlet时必须注意到执行绪的安全问题。
在Servlet 2.4中,单绪执行模型(SingleThreadModel)接口已经被取消,这个接口本来是为了一个Servlet名称产生一组Servlet Pool,以共同分担请求并避免多执行绪存取同一个Servlet所造成的执行绪安全问题,然而如果使用单绪执行模型,可能会产生过多的对象或过多的资源 耗费(例如数据库联机)。
当Servlet被清除之时,会呼叫destroy()方法,通常也建议呼叫super.destroy(),这会呼叫父类别 GenericServlet的destroy(),以在log文件中记录Servlet被清除的讯息,例如:
public void destroy() { super.destroy(); //.... }浏览器发出请求至Servlet的执行顺序是:
浏览器 -> Web 服务器 -> Servlet 容器 -> service()
如果是HttpServlet则会依请求的方法,在service()之后呼叫对应的doXXX()方法。