Servlet的生命周期定义了一个Servlet如何被加载、初始化,以及它怎样接收哀求、响应哀求、提供服务。在网上找到一张关于Servlet生命周期的图解,我在旁边加标了中文(红色表示正常执行的线路,蓝色表示异常抛出)说到生命周期之前,可能先对于几个Servlet方法有个了解会有助于深刻理解Servlet生命周期:
1)init()方法
在Servlet的生命周期中,仅执行一次init()方法。它是在服务器装入Servlet时执行的,可以配置服务器,以在启动服务器或客户机首次访问Servlet时装入Servlet。不管有多少客户机访问Servlet,都不会重复执行init();
2)service()方法
它是Servlet的核心。每当一个客户哀求一个HttpServlet对象,该对象的Service()方法就要调用,而且传递给这个方法一个“哀求”(ServletRequest)对象和一个“响应”(ServletResponse)对象作为参数。在HttpServlet中已存在Service()方法。默认的服务功能是调用与HTTP哀求的方法相应的do功能。
3)destroy()方法
仅执行一次,在服务器端休止且卸载Servlet时执行该方法,有点类似于C++的delete方法。一个Servlet在运行service()方法时可能会产生其他的线程,因此需要确认在调用destroy()方法时,这些线程已经终止或完成。
那么现在开始谈Servlet的生命周期,它始于装入Web服务器的内存时,并在终止或重新装入Servlet时结束。
一、加载和实例化Servlet
Tomcat服务器在如下时刻加载和实例化Servlet:
a) 假如已配置自动装入选项,则在启动服务器时自动载入。
b) 在服务器启动后,客户机首次向Servlet发出哀求时。
c) 重新装入Servlet时。
当启动Servlet容器时,容器首先去查找一个配置文件web.xml,这个文件中记实了可心提供服务的Servlet。每个Servlet被指定一个Servlet名,也就是这个Servlet实际对应的 java的完整class文件名。Servlet容器会为每个自动装入选项的Servlet创建一个实例。所以,每个Servlet类必需有一个公共的无参数的构造器。
二、初始化
当Servlet被实例化后,Servlet容器将调用每个Servlet的init方法来实例化每个实例,执行完init方法之后,Servlet处于“已初始化”状态。所以说,一旦Servlet被实例化,那么必将调用init方法。通过Servlet在启动后不立刻初始化,而是收到哀求后进行。在web.xml文件顶用<load-on-statup> ...... </load-on-statup>对Servlet进行预先初始化。如上图所示,初始化失败后,执行init()方法抛出ServletException异常,Servlet对象将会被垃圾回收器回收,当客户端第一次访问服务器时加载Servlet实现类,创建对象并执行初始化方法;这种情况:如Servlet与一个没有启动的 数据库连接时。
三、哀求处理
对于到达服务器的客户机哀求,服务器创建特定于哀求的一个“哀求”对象和一个“响应”对象。调用service方法,这个方法可以调用其他方法来处理哀求。Service方法会在服务器被访问时调用,Servlet对象的生命周期中service方法可能被多次调用,因为web-server启动后,服务器中公然的部门资源将处于网络中,当网络中的不同主机(客户端)并发访问服务器中的统一资源,服务器将开设多个线程处理不同的哀求,多线程同时处理统一对象时,有可能泛起数据并发访问的错误。
另外留意,多线程难免同时处理统一变量时(如:对统一文件进行写操纵),且有读写操纵时,必需考虑是否加上同步,同步添加时,不要添加范围过大,有可能使程序变为纯粹的单线程,大大削弱了系统机能;只需要做到多个线程安全的访问相同的对象就可以了;
四、终止Servlet
当服务器不再需要Servlet实例或重新装入时,会调用destroy方法,使用这个方法,Servlet可以开释掉所有在init方法申请的资源。一个Servlet实例一旦终止,就不答应再次被调用,只能等待被卸载。
五、卸载Servlet
Servlet一旦终止,Servlet实例即可被垃圾回收,处于“卸载”状态,假如Servlet容器被封闭,Servlet也会被卸载,一个Servlet实例只能初始化一次,但可以创建多个相同的Servlet实例。如相同的Servlet可以在根据不同的配置参数连接不同的数据库时创建多个实例。 |