JavaWeb学习-Servlet系列-3-Servlet的生命周期

àì夳堔傛蜴生んèń 2022-02-04 04:21 411阅读 0赞

上一篇介绍了Servlet的运行过程,知道了一个Servlet类如何在tomcat中被执行。这篇来学习Servlet的生命周期相关的话题。一个Servlet对象被创建之后,到被销毁之前,会执行哪些方法,这些问题是本篇学习需要掌握的。

1.阅读servlet j2ee api文档

注意这个已经不是JDK 1.6 chm那个文档了,Servlet接口只有在j2ee api chm这个文档才能查询得到。如果你本地没有这个文档,你可以去网上下载一个,搜索条件就输入j2ee api chm 中文版之类就能下载到本地。打开这个chm格式文件,搜索servet,内容如下:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTE1NDE5NDY_size_16_color_FFFFFF_t_70

这张图信息比较多,上一篇我们自定义一个servlet类实现了接口Servlet,然后需要我们实现这个接口内的全部方法,我们只在service这个方法中添加一个打印语句,其他方法都没管。

2.Servlet接口必须实现的方法

在前面Servlet初体验这篇文章,以下这几个方法就是实现Servlet接口必须要跟着实现的方法。

  1. public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
  2. System.out.println("Hello Servlet.");
  3. }
  4. @Override
  5. public void destroy() {
  6. // TODO Auto-generated method stub
  7. }
  8. @Override
  9. public ServletConfig getServletConfig() {
  10. // TODO Auto-generated method stub
  11. return null;
  12. }
  13. @Override
  14. public String getServletInfo() {
  15. // TODO Auto-generated method stub
  16. return null;
  17. }
  18. @Override
  19. public void init(ServletConfig config) throws ServletException {
  20. // TODO Auto-generated method stub
  21. }

第一个方法是service(),服务的意思,第二个destroy()是销毁的意思,第三个getServletConfig(),得到Servlet配置信息的方法,第四个getServletInfo()得到Servlet作者信息的方法,第五个init()方法,初始化的意思。这五个方法都是Servlet接口的方法。

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3UwMTE1NDE5NDY_size_16_color_FFFFFF_t_70 1

3.生命周期方法

在Servlet接口介绍文字中提到生存周期方法,而且按照一定顺序执行

20190506215703260.png

对着API文档,初始化servlet其实说的就是Init()方法,服务于请求说的就是service()方法,从服务器删除说的是destroy()方法。然后我们来看上面1,2,3这顺序的意思。

先是执行Servlet自定义类的构造方法,默认是一个无参的空构造。然后执行init()进行初始化。第三service()方法,最后如果服务器把这个servlet删除,会执行destroy方法,最后垃圾回收是JVM干的活。

也就是生命周期三个方法,getServletConfig()和getServletInfo()两个方法不是重点,本篇不关注这两个方法,本篇重点来学习生命周期提到三个方法。init() service()destrou()

4.验证生命周期方法执行顺序

下面我们来验证下这个API文档说的生命周期中方法的执行顺序问题。

我们先准备一个web项目,和servlet初体验差不多一样。这里ServletDemo1.java代码贴出来,web.xml和前面这一篇是一样。

  1. package com.anthony.servlet;
  2. import java.io.IOException;
  3. import javax.servlet.Servlet;
  4. import javax.servlet.ServletConfig;
  5. import javax.servlet.ServletException;
  6. import javax.servlet.ServletRequest;
  7. import javax.servlet.ServletResponse;
  8. public class ServletDemo1 implements Servlet {
  9. // 把无参构造写出来,写一个打印语句,方便测试观察执行顺序
  10. public ServletDemo1() {
  11. System.out.println("********构造方法被执行*************");
  12. }
  13. @Override
  14. public void init(ServletConfig arg0) throws ServletException {
  15. System.out.println("********init方法被执行*************");
  16. }
  17. @Override
  18. public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {
  19. System.out.println("********service方法被执行*************");
  20. }
  21. @Override
  22. public void destroy() {
  23. System.out.println("********destroy方法被执行*************");
  24. }
  25. @Override
  26. public ServletConfig getServletConfig() {
  27. // TODO Auto-generated method stub
  28. return null;
  29. }
  30. @Override
  31. public String getServletInfo() {
  32. // TODO Auto-generated method stub
  33. return null;
  34. }
  35. }

我分别在构造方法,init方法,service()和destroy()方法添加一行打印语句。把代码部署到tomcat上,然后点击启动tomcat服务,浏览器测试打开http://localhost:8080/Servlet01/demo

我这边可以在Eclipse上控制台看到这个输出

  1. 五月 06, 2019 10:30:36 下午 org.apache.catalina.startup.Catalina start
  2. 信息: Server startup in 914 ms
  3. ********构造方法被执行*************
  4. ********init方法被执行*************
  5. ********service方法被执行*************

上面的日志是我只请求了一次http://localhost:8080/Servlet01/demo的效果,方法执行效果,确实是先构造方法,然后init方法,然后service方法。下面我在浏览器多刷新几次http://localhost:8080/Servlet01/demo这个地址,再次看看Eclipse控制台输出

  1. ********构造方法被执行*************
  2. ********init方法被执行*************
  3. ********service方法被执行*************
  4. ********service方法被执行*************
  5. ********service方法被执行*************
  6. ********service方法被执行*************

得到一个结论,刷新几次,也就是servlet请求了几次,就会执行几次service()方法,而构造方法和init初始化方法只运行一次、下面就缺一个destroy方法被执行了,我这里Eclipse上直接点击关闭tomcat服务,也就是应用Servlet01服务器肯定挂了,看看能不能执行destroy方法。

  1. 信息: Server startup in 914 ms
  2. ********构造方法被执行*************
  3. ********init方法被执行*************
  4. ********service方法被执行*************
  5. ********service方法被执行*************
  6. ********service方法被执行*************
  7. ********service方法被执行*************
  8. 五月 06, 2019 10:37:26 下午 org.apache.catalina.core.StandardServer await
  9. 信息: A valid shutdown command was received via the shutdown port. Stopping the Server instance.
  10. 五月 06, 2019 10:37:26 下午 org.apache.coyote.AbstractProtocol pause
  11. 信息: Pausing ProtocolHandler ["http-nio-8080"]
  12. 五月 06, 2019 10:37:27 下午 org.apache.coyote.AbstractProtocol pause
  13. 信息: Pausing ProtocolHandler ["ajp-nio-8009"]
  14. 五月 06, 2019 10:37:27 下午 org.apache.catalina.core.StandardService stopInternal
  15. 信息: Stopping service [Catalina]
  16. ********destroy方法被执行*************
  17. 五月 06, 2019 10:37:27 下午 org.apache.catalina.core.ApplicationContext log
  18. 信息: SessionListener: contextDestroyed()
  19. 五月 06, 2019 10:37:27 下午 org.apache.catalina.core.ApplicationContext log
  20. 信息: ContextListener: contextDestroyed()
  21. 五月 06, 2019 10:37:27 下午 org.apache.coyote.AbstractProtocol stop
  22. 信息: Stopping ProtocolHandler ["http-nio-8080"]
  23. 五月 06, 2019 10:37:27 下午 org.apache.coyote.AbstractProtocol stop
  24. 信息: Stopping ProtocolHandler ["ajp-nio-8009"]
  25. 五月 06, 2019 10:37:27 下午 org.apache.coyote.AbstractProtocol destroy
  26. 信息: Destroying ProtocolHandler ["http-nio-8080"]
  27. 五月 06, 2019 10:37:27 下午 org.apache.coyote.AbstractProtocol destroy
  28. 信息: Destroying ProtocolHandler ["ajp-nio-8009"]

果然关闭了tomcat服务,这个servlet方法destroy()会被执行,也就是servlet这个对象就销毁了,直接让JVM垃圾回收了。上面这个过程就是一个servlet的生命周期过程,先执行构造方法,然后执行init方法初始化对象,然后浏览器发送几次请求,就执行几次service()方法,销毁方法只有在tomcat服务挂了或者应用项目Servlet01出现问题了才会被执行销毁,从而垃圾回收,这样完整的servlet生命周期过程就介绍完了。

5.小知识点-如何让servlet在tomcat服务器启动就创建呢

从上面我们知道,启动tomcat服务器之后,我们需要手动去浏览器触发请求,这个servlet才能被调用构造方法,然后调用init方法进行初始化。那么有没有办法,让tomcat服务器一起动就创建servlet对象并初始化。

这个需要在web.xml中添加一个标签,下面load-on-startup中2是权重的意思,数字越小,优先级越高,如果有多个servlet对象。

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  3. <servlet>
  4. <servlet-name>servletDemo1</servlet-name>
  5. <servlet-class>com.anthony.servlet.ServletDemo1</servlet-class>
  6. <load-on-startup>2</load-on-startup>
  7. </servlet>
  8. <servlet-mapping>
  9. <servlet-name>servletDemo1</servlet-name>
  10. <url-pattern>/demo</url-pattern>
  11. </servlet-mapping>
  12. <welcome-file-list>
  13. <welcome-file>index.html</welcome-file>
  14. <welcome-file>index.htm</welcome-file>
  15. <welcome-file>index.jsp</welcome-file>
  16. <welcome-file>default.html</welcome-file>
  17. <welcome-file>default.htm</welcome-file>
  18. <welcome-file>default.jsp</welcome-file>
  19. </welcome-file-list>
  20. </web-app>

重新发布到tomcat,并启动tomcat看看Eclipse控制台输出效果。

  1. 信息: Starting service [Catalina]
  2. 五月 06, 2019 10:49:38 下午 org.apache.catalina.core.StandardEngine startInternal
  3. 信息: Starting Servlet Engine: Apache Tomcat/8.5.40
  4. ********构造方法被执行*************
  5. ********init方法被执行*************
  6. 五月 06, 2019 10:49:38 下午 org.apache.catalina.startup.HostConfig deployDirectory
  7. 信息: Deploying web application directory [F:\apache-tomcat-8.5.40\webapps\docs]
  8. 五月 06, 2019 10:49:38 下午 org.apache.catalina.startup.HostConfig deployDirectory
  9. 信息: Deployment of web application directory [F:\apache-tomcat-8.5.40\webapps\docs] has finished in [23] ms
  10. 五月 06, 2019 10:49:38 下午 org.apache.catalina.startup.HostConfig deployDirectory
  11. 信息: Deploying web application directory [F:\apache-tomcat-8.5.40\webapps\examples]
  12. 五月 06, 2019 10:49:39 下午 org.apache.catalina.core.ApplicationContext log
  13. 信息: ContextListener: contextInitialized()
  14. 五月 06, 2019 10:49:39 下午 org.apache.catalina.core.ApplicationContext log
  15. 信息: SessionListener: contextInitialized()
  16. 五月 06, 2019 10:49:39 下午 org.apache.catalina.core.ApplicationContext log
  17. 信息: ContextListener: attributeAdded('StockTicker', 'async.Stockticker@53ae374')
  18. 五月 06, 2019 10:49:39 下午 org.apache.catalina.startup.HostConfig deployDirectory
  19. 信息: Deployment of web application directory [F:\apache-tomcat-8.5.40\webapps\examples] has finished in [408] ms
  20. 五月 06, 2019 10:49:39 下午 org.apache.catalina.startup.HostConfig deployDirectory
  21. 信息: Deploying web application directory [F:\apache-tomcat-8.5.40\webapps\host-manager]
  22. 五月 06, 2019 10:49:39 下午 org.apache.catalina.startup.HostConfig deployDirectory
  23. 信息: Deployment of web application directory [F:\apache-tomcat-8.5.40\webapps\host-manager] has finished in [35] ms
  24. 五月 06, 2019 10:49:39 下午 org.apache.catalina.startup.HostConfig deployDirectory
  25. 信息: Deploying web application directory [F:\apache-tomcat-8.5.40\webapps\manager]
  26. 五月 06, 2019 10:49:39 下午 org.apache.catalina.startup.HostConfig deployDirectory
  27. 信息: Deployment of web application directory [F:\apache-tomcat-8.5.40\webapps\manager] has finished in [28] ms
  28. 五月 06, 2019 10:49:39 下午 org.apache.catalina.startup.HostConfig deployDirectory
  29. 信息: Deploying web application directory [F:\apache-tomcat-8.5.40\webapps\ROOT]
  30. 五月 06, 2019 10:49:39 下午 org.apache.catalina.startup.HostConfig deployDirectory
  31. 信息: Deployment of web application directory [F:\apache-tomcat-8.5.40\webapps\ROOT] has finished in [21] ms
  32. 五月 06, 2019 10:49:39 下午 org.apache.coyote.AbstractProtocol start
  33. 信息: Starting ProtocolHandler ["http-nio-8080"]
  34. 五月 06, 2019 10:49:39 下午 org.apache.coyote.AbstractProtocol start
  35. 信息: Starting ProtocolHandler ["ajp-nio-8009"]
  36. 五月 06, 2019 10:49:39 下午 org.apache.catalina.startup.Catalina start
  37. 信息: Server startup in 910 ms

效果出来了,tomcat服务器还没有看到启动成功,这个servlet就调用了构造方法和init初始化方法。

发表评论

表情:
评论列表 (有 0 条评论,411人围观)

还没有评论,来说两句吧...

相关阅读