Servlet生命周期的四个阶段
1.实例化servlet对象:Servlet 容器创建 Servlet 的实例
有两种方式:1):通过配置文件web.xml进行实例化
2):注解
2.初始化参数配置: 该容器调用 init ( ServletConfig ) 方法
servlet实例化后就会调用init方法,只能调用一次,且是在进行第一次实例化servlet对象时调用。当用户在调用servlet时,就会创建一个servlet实例,每一次在客户端发送的请求servlet就会产生一个新的线程,从而调用对应的doGet 或 doPost 方法。
配置参数的方式有两种:1):通过配置文件web.xml方式配置
2):通过注解方式配置
3.服务:如果请求 Servlet,则容器调用 service() 方法
service()方法是执行实际任务的主要方法,Web服务器将调用service方法处理客户端(浏览器)的请求,然后将格式化的数据响应给浏览器客户端。每当客户端向服务端发送一个请求时,服务端都会产生一个新的线程调用服务。调用service方法中的 doGet、doPost、doPut进行实际的业务逻辑进行处理。
4.销毁:销毁实例之前调用 destroy() 方法
servlet生命周期结束时将会调用destroy()方法,并且只会调用一次。destroy方法可以让我们的servlet关闭数据库连接,把后台线程关闭,清楚Cookie数据等。当调用了destroy()方法后,当前servlet实例将会被标记为回收垃圾,会对servlet实例进行清除。
Servlet不是线程安全的。
当Tomcat接收到HTTP请求时,Tomcat从线程池中取出一个线程,之后找到该请求对应的Servlet对象并进行初始化,之后调用service()方法。而每一个Servlet对象在Tomcat容器中只有一个实例对象,即单例模式。如果多个HTTP请求请求的是同一个Servlet,那么着两个HTTP请求对应的线程将并发调用Servlet的service()方法。
上图中的Thread1和Thread2调用了同一个Servlet1,所以此时如果Servlet1中定义了实例变量或静态变量,那么可能会发生线程安全问题(因为所有的线程都可能使用这些变量)。