Servlet生命周期

容器初始化
     当Servlet容器(tomcat)启动时,它会部署并加载所有的web应用。当web应用被加载时,Servlet容器会一次性为每个应用创建Servlet上下文(ServletContext)并把它保存在内存里。Servlet容器会处理web应用的web.xml文件,并且一次性创建在web.xml里定义的Servlet、Filter和Listener
 
   ServletContext定义了一组方法,Servlet使用这些方法来与它的Servlet容器进行通信。例如,用来获取文件的MIME类型、转发请求或者编写日志文件。
 
 当客户端(使用web浏览器的用户)发送一个HTTP请求时,Servlet容器会创建新的HttpServletRequest和HttpServletResponse对象,并且把它们传递给已经创建的Filter和URL模式与请求URL匹配的Servlet实例的方法,所有的这些都使用同一个线程。
而ServletContext通过一个映射类。映射到相应的Servlet容器
 
Servlet流程
Servlet类图:
Servlet生命周期
事实上,Servlet是一个在javax.servlet包里定义的接口。它为Servlet的生命周期声明了三个基本方法——init()、service()和destroy()。每个Servlet都要实现这些方法(在SDK里定义或者用户定义)并在它们的生命周期的特定时间由服务器来调用这些方法。
 
1.Servlet 通过调用 init () 方法进行初始化。
与 Servlet 主动关联的是三个类,分别是 ServletConfig、ServletRequest 和 ServletResponse。Servlet使用 ServletContext 来进行传递参数,构建交互场景。
ServletConfig 是在 Servlet init 时由容器传过来的,ServletConfig把配置信息交给 ServletContext 。ServletRequest 和 ServletResponse则封装了交互信息。他们最终 转化为 HttpServletRequest 和 HttpServletResponse。
2.在Servlet的整个生命周期内,Servlet的init方法只被调用一次。而对一个Servlet的每次访问请求都导致Servlet引擎调用一次servlet的service方法。对于每次访问请求,Servlet引擎都会创建一个新的HttpServletRequest请求对象和一个新的HttpServletResponse响应对象,然后将这两个对象作为参数传递给它调用的Servlet的service()方法,service方法再根据请求方式分别调用doXXX方法。
3。destory负责销毁,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。
 
Session
当客户端第一次访问web应用或者第一次使用request.getSession()获取HttpSession时,Servlet容器会创建Session,生成一个long类型的唯一ID(你可以使用session.getId()获取它)并把它保存在服务器的内存里。Servlet容器同样会在HTTP响应里设置一个Cookie,cookie的名是JSESSIONID并且cookie的值是session的唯一ID
 
线程安全
当客户端第一次请求某个Servlet时,Servlet容器将会根据web.xml配置文件实例化这个Servlet类。当有新的客户端请求该Servlet时,一般不会再实例化该Servlet类,也就是有多个线程在使用这个实例。
解决:
1.实现SingleThreadModel接口
这个接口相当于对每个请求当读实例化一个servlet,不推荐
2.可能共享的数据使用synchronized手动加锁
3.避免实例变量