Servlet生命周期(代码+图示)
在网上看了一些文章,感觉理论性太强了,现在我们先简单说一下Servlet的生命周期,然后用代码进行验证。
当游览器访问服务器时,服务器对url进行解析,如果游览器要的不是静态资源,服务器就根据URI访问对应的Servlet,以tomcat为例,tomcat首先会判断Servlet是否被实例化了,因为在默认情况下Servlet是单例的,也就是只会被创建一次(等会代码演示),如果没有被创建,也就表示这是第一次访问,然后tomcat就会创建对应的Servlet的实例对象,然后放入类似于HashMap的容器中进行管理,并且调用Servlet的init方法,然后再调用Servlet的service方法。如果不是第一次,那么tomcat就会直接调用service方法。最后,当tomcat关闭时,Servlet就会被销毁,但是销毁前会调用destroy方法。下面用图和代码进行演示。
下面给出Servlet生命周期中所遵循的过程
-
Servlet 初始化后调用 init () 方法。 Servlet 调用 service() 方法来处理客户端的请求。 Servlet 销毁前调用 destroy() 方法。 最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。
图示大致为
我们首先来验证上面所说的Servlet是单例的,也就是只会创建一次,测试代码如下
import javax.servlet.*; import javax.servlet.annotation.WebServlet; import javax.servlet.http.*; import java.io.IOException; @WebServlet("/single") public class SingleServlet extends HttpServlet { private int count = 0; @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("当前servlet访问次数为:" + ++count); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }
我们在代码中定义了一个私有的属性count来记录访问次数,如果每次访问的输出都是1,那么我们的Servlet就不是单例的,如果输出的count一值加1,那么就是单例的,我们启动服务器来访问一下,看控制台输出情况。
我们访问了4次,发现访问次数每次都增加,也验证了Servlet是单例的,既然是单例,那么我们就可以肯定的知道该类只会被初始化一次,又因为init方法在创建时才会调用,所以init也只会调用一次。同理,destroy也是。我们还是设计一个test来说明,代码如下
import javax.servlet.*; import javax.servlet.annotation.WebServlet; import javax.servlet.http.*; import java.io.IOException; @WebServlet("/life") public class LifeServlet extends HttpServlet { @Override public void init() throws ServletException { System.out.println("调用了init方法"); } @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("调用了service方法"); } @Override public void destroy() { System.out.println("调用了destroy方法"); } }
我们启动服务器,并且进行第一次访问
果然,第一次访问先创建Servlet实例对象,然后调用init方法,然后调用service方法,我们继续访问第二次。
和我们想的一样,因为已经存在该Servlet的实例对象了,所以直接调用service方法,我们多访问几次试一下。
发现确实是只调用了service方法。最后我们关闭tomcat。
果然,这个也和想的一样,Servlet在服务器关闭时被销毁,销毁前调用destroy方法。