前面已经分析过session的持久化和session管理器,本文继续结合session的生命周期,进一步的分析session是如何在浏览器请求过程中创建的,梳理整个session请求链条。
1.再谈SessionID
浏览器客户端的请求,经过Tomcat前端的工作线程池,简单解析socket,初始化Request,传入到Tomcat后端容器的起始位置,CoyoteAdaptor类的service:

熟读Tomcat代码的人都应该知道,该类是Tomcat前端和后端容器的一个分水岭,CoyoteAdaptor会基于request进一步的解析,在这个过程中,会查看客户端是否有sessionId,如果有sessionId,那么客户端判定该请求是属于上一次的session会话中,如果没有的,会给这个请求产生一个sessionId:

这段代码的逻辑,我们在StandardSession中简单分析过,一共分为三种情况,对应三种不同的SessionTrackingMode:
a.第一种,就是url重写,从代码看到,直接其实在url中找jsessionid的参数,如果有的话,就代表有sessionid
b.第二种,cookie,对于web.xml前面讲到了可以配置cookie的名称,这里通过配置进行读取,看是否能找到sessionid
c.第三种,ssl下的sessionid,获取方法和http的有很大不同,这个在ssl交互中再进行介绍
到这里为止,我们就可以得出结论,一个reqeust请求,必定对应一个sessionid;
很多人以为,只有我在servlet中调用了request.getSession,这个时候才会有sessionid关联,这个绝对是错误的,sessionid的创建和你客户端怎么写是无关的;
而当你调用request.getSession的时候,实际上是使用是否创建ManagerBase中的session对象的集合:

如果客户端中没有调用到和session代码,那么这个Standardsession就不会创建;
因此,这就要求客户端在编写代码的时候,一定要注意,如果根本没有用到session,自己代码中一顿瞎写,那么一旦并发量比较大的话,会生成一些没有用的Standardsession对象,无故消耗系统内存;
2.getSession
我们再从Request.getSession的代码中进行分析一下上述的思路。

从上面的流程上,总共分成6个步骤,基本是按照这个思路,先去查询客户端传递过来的sessionid,是否在服务器端的session集合中,如果不在就需要创建,调用Session管理器,StanardManager或者配置的PersistentManager去createSession;
3.Session生命周期状态图
经过这几节的研究,到这里为止,Session就完整的清晰的看到请求中是如何创建出来的,所以我们可以总结出来下面的图,作为Session生命周期的状态变换:

总结:
session初始化比较重要的是区别sessionid的生成,和standardsession的生成,如果将这两点区分好的话,这篇文章就没白看!




