Servlet对象的生命周期
IDEA 创建基于 Maven 的 webapp
- 第一步:IDEA 创建空工程
- 第二步:IDEA 创建模块,build system 选择 Maven,修改 GroupId
- 第三步:在 main 目录下创建 webapp 目录,webapp 目录下创建 WEB-INF
- 第四步:在 WEB-INF 目录下创建 web.xml

- 第五步:填写 web.xml,建议从其他地方复制,例如从 TomcatRoot -> webapps -> examples 项目中复制,删除多余的内容,仅保留一个 servlet 和 servlet-mapping 作为后续参考
- 第六步:编辑 pom.xml,修改打包方式为 war
- 第七步:编辑 pom.xml,引入 javax.servlet-api 依赖,重新加载 Maven

- 第八步:在代码包路径下创建 Servlet 类,例如 QueryRoomServlet,实现 Servlet 接口
- 第九步:编辑 web.xml,配置 servlet 和 servlet-mapping

- 第十步:编辑 Configuration,增加一个 SmartTomcat 的 Configuration
- 第十一步:配置 Configuration
- Deployment directory : webapp 路径
- Use classpath of module : hotel
- Context path: /hotel

什么是Servlet对象的生命周期
- Servlet对象的生命周期:一个 Servlet 对象从出生(创建)到死亡(销毁)的整个过程。

Servlet 对象的 service 方法什么时候被调用
- 验证方法:
- 我们在 service 方法中打印内容,在浏览器中反复刷新请求,观察输出内容。
- 结论:
- service 方法在用户访问 Servlet 对象的请求路径时被调用。
- 请求一次就会调用一次。
- service 方法的作用:
- service 方法是用来提供服务的,执行业务逻辑的。例如“查询空房”,“预定房间”。
Servlet 对象什么时候实例化
验证方式:为 Servlet 类创建无参构造函数。
- Servlet 对象由 web 服务器利用反射机制调用无参构造函数创建。因此,无参构造函数被调用的时刻,就是 Servlet 对象实例化的时刻。
Servlet 对象是在服务器启动时被实例化的么?
- 不是,默认情况下,服务器启动时 Servlet 对象不会被实例化。
Servlet 对象实例化的时机
为什么默认不在服务启动时实例化 Servlet 对象?
有没有办法在服务器启动时就实例化 Servlet 对象?
- 有,配置 load-on-startup,数字越小优先级越高

Servlet 对象创建了几个
- 验证方法:
- 我们在 service 方法中打印当前对象的地址,在浏览器中反复刷新请求,观察每次打印的对象地址。
- 结论:
- 每次请求,service 方法被执行,打印的对象地址相同,证明每次执行请求的都是同一个 Servlet 对象。
- 无参构造方法只被调用了一次,也证明了 Servlet 对象只创建了一个。
- Servlet 对象是单例(单实例)的,创建之后就保存下来,需要时取出来使用。
Servlet 对象的 init 方法什么时候被调用
- 验证方法:
- 我们在 init 方法中打印内容,在浏览器中反复刷新请求,观察输出内容。
- 结论:
- init 方法在无参构造方法执行完成后(即 Servlet 对象被创建出来后)被调用。
- init 方法只被调用一次。
- init方法的作用:
- 有些场景下,Servlet 对象被创建出来之后,需要执行初始化之后才能提供服务,例如连接数据库。
- 类比,人类出生之后,需要接受教育后(假设只接受一次教育),才能够工作。
- 为什么需要 init 方法?为什么不在无参构造函数中编写初始化的逻辑?
- 可以在无参构造函数中编写初始化逻辑,但不建议这么做。
- 不建议程序员创建无参构造函数,一旦误给无参构造函数加上参数,会导致 Servlet 无法被实例化。
- 对象创建出来后在 init 方法中执行初始化,这种设计思想很常见,在多种框架,例如 Spring 中也会用到。
Servlet对象的 destroy 方法什么时候被调用
- 验证方法:
- 我们在 destroy 方法中打印内容,观察输出内容。
- 结论:
- Servlet 对象的 destroy 方法在服务关闭前被调用。
- destroy方法的作用:
- 用于释放资源,例如关闭数据库连接。
- 类比,人类出生之后,需要接受教育后(假设只接受一次教育),才能够工作,临死前需要交待后事。
- destroy方法被调用时,Servlet 对象是否已经被销毁?
- destroy方法被调用时,Servlet对象还没有被销毁,因为 destroy 方法是实例方法,必须有对象存在才能被调用。
Servlet 对象生命周期总结

- Servlet 对象默认在第一次请求到来时创建,如果配置了 load-on-startup 是在服务启动时创建。
- init 方法在对象创建完成后被调用。
- Servlet 是单实例的,一个 Servlet 类只创建一个对象,init 方法只调用一次。
- 每次请求都会调用 service 方法。
- 接收到服务关闭指令,在Servlet对象销毁前会调用 destroy 方法,destroy 方法只执行一次。
Servlet 对象由谁来维护 – web 容器的概念
Servlet 对象由谁来维护?
- 显然不是 webapp 的开发者,因为我们自始至终都没有自己创建 Servlet 对象,没有调用 Servlet 对象的方法。
- Servlet 对象是由 web 服务器维护的,我们课程中使用的是 Tomcat,我们又将其称为 web 容器。
什么是容器
- 容器(Container),用于容纳物品的以壳体为主的装置。
什么是 web 容器
- Web 容器( Web Container),用于存放 Servlet 对象,管理 Servlet 对象的整个生命周期。
- Web 容器负责:
- 在合适的时机创建 Servlet 对象,并执行 Servlet 对象的 init 方法初始化对象。
- 调用 Servlet 对象的 service 方法响应用户请求
- 在服务关闭前销毁对象,并在销毁前调用对象的 destroy 方法。