首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 开源软件 >

Tomcat源码之Session兑现

2012-07-05 
Tomcat源码之Session实现???? 前段时间看了阵子Tomcat的源码,有所得。早想总结出来可惜太多了,不知道从何说

Tomcat源码之Session实现

???? 前段时间看了阵子Tomcat的源码,有所得。早想总结出来可惜太多了,不知道从何说起,今天早上有时间先从Session如何实现的说起吧,免得时间越久忘记的越多。

?????Tomcat的容器有四个级别,分别为Engine、Host、Context和Wrapper。所有的容器都有相同的父类,即org.apache.catalina.core.ContainerBase。那么session的管理在哪个级别的,Engine、Host还是Context?答案是在Context级别实现的,即每个应用有自己的session管理对象。

????? StandardContext是Context容器(即你的应用)的标准实现,在其start方法中(即启动时候)将创建该应用的session管理对象,非集群的情况下Session管理对象类为org.apache.catalina.session.StandardManager,它是session的标准管理器,每个Context(应用)关联一个,它实现了session的创建、查询、过期检测和序列化和反序列化,序列化和反序列化是在容器重启过程中用到的,保证重启不会丢失活动的session。

??????StandardContext的父类是org.apache.catalina.session.ManagerBase,其session的保存变量声明为protected Map<String, Session> sessions = new ConcurrentHashMap<String, Session>();即利用ConcurrentHashMap保存session,如果想所有的应用共用一个session可以先将此变量设置为static的,然后修改设置cookie的JSESSION的path为“/”。

????? Session的创建——当request.getSession时候,根据请求中cookie中的或者url后的JSESSION参数查找session,如果存在则返回相应的session,不存在则创建并在响应(response)设置头信息,要求设置客户端cookie的JSESSION为session的id,path为应用的路径。

????? Session的过期检测——session的超时检测如何实现的呢?

????? 在ContainerBase中有个ContainerBackgroundProcessor类。该类如下:

?????

Object listeners[] = context.getApplicationLifecycleListeners();                if (notify && (listeners != null)) {                    HttpSessionEvent event =                        new HttpSessionEvent(getSession());                    for (int i = 0; i < listeners.length; i++) {                        int j = (listeners.length - 1) - i;                        if (!(listeners[j] instanceof HttpSessionListener))                            continue;                        HttpSessionListener listener =                            (HttpSessionListener) listeners[j];                        try {                            fireContainerEvent(context,                                               "beforeSessionDestroyed",                                               listener);                            listener.sessionDestroyed(event);                            fireContainerEvent(context,                                               "afterSessionDestroyed",                                               listener);                        } catch (Throwable t) {                            try {                                fireContainerEvent(context,                                                   "afterSessionDestroyed",                                                   listener);                            } catch (Exception e) {                                // Ignore                            }                            manager.getContainer().getLogger().error                                (sm.getString("standardSession.sessionEvent"), t);                        }                    }                }

?? ?如果监听为对Session的监听,则触发监听,而在创建session的设置session的id方法中会调用tellNew(),其会触发session创建时session监听程序。

??? 就这么多吧,要上班了。。。

?

热点排行