这一章是关于session,tomcat是用manager组件来对session进行管理的,见org.apache.catalina.Manager接口。
一个manager通常和一个context关联,负责session的创建、更新、销毁等。
默认情况下,session是放在内存中的,但tomcat也提供了其它方式,比如放到文件或数据库中。
一,Sessions
如图,HttpSession是系统外部的facade,而Session是系统内部的facade。
1,Session interface
提供的方法比较多,只说其中几个:
一个session要和一个manager关联,所以有
public Manager getManager();
public void setManager(Manager manager);
一个session要通过id辨别
public String getId();
public void setId(String id);
public long getLastAccessedTime();
session通过以上方法决定这个session是否可用,也就是检查它是否过期。
通过public void setValid(boolean isValid);来具体设置。
public void access();
每当session被访问,上述方法被调用来更新最后访问时间,也就是LastAccessedTime。
public void expire();
用于设置session过期。
public HttpSession getSession();
返回session
2,The StandardSession Class
这个是session的实现类,它实现了HttpSession、Session,还有Serializable接口。
此类的构造方法包含一个manager类的参数,这样就保证了一个Session必须和一个manager关联。
类中有n多变量,有些是transient的,标志不被序列化。在tomcat 5中,这些变量是protected,但4中是private的。
getSession方法创建一个相应的facade类返回回去。在创建facade类时,吧this当参数传过去。
public HttpSession getSession() {
if (facade == null) facade = new StandardSessionFacade(this);
return (facade);
}
如果没有访问session的时间超过了maxInactiveInterval指定的时间,则这个session将过期,expire方法会被调用。expire的代码就不粘了,它里面主要是设置expire变量,从manager里remove这个session和发起一些event。
3,The StandardSessionFacade Class
这个在第二章中讲了。
二,Manager
manager接口的实现类是ManagerBase,ManagerBase又有两个子类:
1,StandardManager 用于将session存储在内存中,如果服务器停了,把内存中的信息存在一个file中,服务器启动时再把file中的信息读到内存。
2,PersistentManagerBase 把session存储在二级缓存。有两个子类:PersistentManager and DistributedManager
(一)The Manager Interface
不多说了,里面定义的方法都能看懂。
因为manager会和context关联,所以当然有setcontainer,getcontainer。
manager管理session,就有createSession,add(把session放到session pool中),remove。
getMaxInactiveInterval and the setMaxInactiveInterval这个是设置最大允许不访问此session时间。如果超过这个时间不访问session,此session会expire。
load和unload方法用于把内存和二级存储中的session互相传输。
(二)The ManagerBase Class
是个abstract类。提供了generateSessionId方法,顾名思义生成session id用的。
一个manager管理相关context的所有active的session(active包括valid),并把这些session放在一个map里:
protected HashMap sessions = new HashMap();
所以,那些add,find,remove方法就可想而知了,都是对这个hashmap进行简单操作。
(三)StandardManager
这个类实现了Lifecycle,所以可以被Start或stop。在stop时,它会将内存中的session信息unload到CATALINA_HOME/work目录下的SESSIONS.ser文件中,每个context生成一个SESSIONS.ser。
对过期的处理:
StandardManager实现了Runnable接口,所以它在一个单独的线程中运行,看看它的run方法:
public void run() {
// Loop until the termination semaphore is set
while (!threadDone) {
threadSleep();
processExpires();
}
}
具体代码不多说了,说下思路。这个run方法一直跑,每间隔一段时间,就对所有session进行一次检查,看看它们的最后访问时间lastAccessedTime和现在时间的差是否超过了预设MaxInactiveInterval ,如果超过了,就调用session的expire方法把它过期了。关于时间间隔的长度,由checkInterval变量设定。
checkInterval和
MaxInactiveInterval得默认值都是60,但
MaxInactiveInterval会被修改成用户设定的timeout时间,这是在setContainer里设定的
(默认的sessionTimeOut是30)
:
setMaxInactiveInterval(((Context) this.container).getSessionTimeout()*60 );
在tomcat 5中,
StandardManager类不实现Runnable接口。检查session过期是通过调用backgroundprocess方法。
public void backgroundProcess() { processExpires(); }
关于此方法,会在12章讲述。大致意思是在tomcat 5中会专门有一个线程处理那些后台需要跑的程序。
三,Application
关于把session信息放到二级存储的类先不介绍了。
总结一下:
首先,当tomcat启动时,manager组件也启动,start方法被调用,主要做两件事:一是把file中的session信息load到内存;二是启动manager线程来监控session是否过期。
然后,当用户第一次调用httpservletrequest的getSession方法时(getSession有个bool型参数,如果是true,则新创建一个session,反之返回null),request调用manager的createSession方法新建一个session,并把这个session赋值到request的属性中。之后再getSession时就可以直接返回这个属性了。
manager一直跑着的检查过期的线程,每隔一段时间间隔就检查session是否过期。如果过期了,用户再调getSession,那么就又新建一个session。
最后当tomcat stop时,manager负责把内存中的session信息unload到文件中去。