Tomcat Session管理

Catalina通过一个称为Session管理器的组件来管理建立Session对象,该组件由org.apache.catalina.Manager接口表示。Session管理器需要与一个Context容器相关联,且必须与一个Context容器关联。相比于其他组件,Session管理器负责创建、更新、销毁Session对象,当请求来了,要返回一个有效的Session对象。

默认情况下,Session管理器会将其所管理的Session对象存放在内存中。但是,在Tomcat中,Session管理器也可以将Session对象进行持久化,存储到文件存储器或者通过JDBC写入到数据库中。

session相关的如下图:

1.Session一个接口,用于维护状态信息的HttpSession,对于用户的请求维持状态。看一下一些常量和部分接口方法。

public interface Session {
public static final String SESSION_CREATED_EVENT = "createSession";
/**
* The SessionEvent event type when a session is destroyed.
*/
public static final String SESSION_DESTROYED_EVENT = "destroySession";
/**
* The SessionEvent event type when a session is activated.
*/
public static final String SESSION_ACTIVATED_EVENT = "activateSession";
/**
* The SessionEvent event type when a session is passivated.
*/
public static final String SESSION_PASSIVATED_EVENT = "passivateSession";
/**
* Return the creation time for this session.
*/
public long getCreationTime();
/**
* Return the session identifier for this session.
*/
public String getId();
/**
* Return the <code>HttpSession</code> for which this object
* is the facade.
*/
public HttpSession getSession();
/**
* Add a session event listener to this component.
*/
public void addSessionListener(SessionListener listener);
/**
* Perform the internal processing required to invalidate this session,
* without triggering an exception if the session has already expired.
*/
public void expire();
}

2.StandardSession实现了Session、HttpSession、Serializable接口(便于session序列化) 
部分方法:

/**
* Add a session event listener to this component.
*/
@Override
public void addSessionListener(SessionListener listener) {
listeners.add(listener);
}
public void readObjectData(ObjectInputStream stream)
throws ClassNotFoundException, IOException { readObject(stream); }
public void writeObjectData(ObjectOutputStream stream)
throws IOException { writeObject(stream); }
//获取Session里面的值
public Object getAttribute(String name) { if (!isValidInternal())
throw new IllegalStateException
(sm.getString("standardSession.getAttribute.ise")); if (name == null) return null; return (attributes.get(name)); }
/**
* The collection of user data attributes associated with this Session.
*/
protected Map<String, Object> attributes = new ConcurrentHashMap<String, Object>();
//触发事件
public void fireSessionEvent(String type, Object data) {
if (listeners.size() < 1)
return;
SessionEvent event = new SessionEvent(this, type, data);
SessionListener list[] = new SessionListener[0];
synchronized (listeners) {
list = listeners.toArray(list);
} for (int i = 0; i < list.length; i++){
(list[i]).sessionEvent(event);
} }

3.Manager是一个Session管理器组件负责管理Session对象。提供了getContainer()和setContainer()方法,以便于一个容器相关联,createSession()方法用来创建Session实例。add方法将Session添加到session池中。其中load和unload用来将session对象持久化处理,unload将会包session对象存储到指定介质,load将session对象加载到内存中。

4.ManagerBase实现了Manager接口并实现了一些方法。

/**
* The default maximum inactive interval for Sessions created by
* this Manager.
* session默认有效时间30分钟
*/
protected int maxInactiveInterval = 30 * 60;
/**
* The set of currently active Sessions for this Manager, keyed by
* session identifier.
* session池
*/
protected Map<String, Session> sessions = new ConcurrentHashMap<String, Session>();
/**
* Invalidate all sessions that have expired.
* 判断所有的session是否失效,实现原理是通过一个线程定期检查。
*/
public void processExpires() { long timeNow = System.currentTimeMillis();
Session sessions[] = findSessions();
int expireHere = 0 ; if(log.isDebugEnabled())
log.debug("Start expire sessions " + getName() + " at " + timeNow + " sessioncount " + sessions.length);
for (int i = 0; i < sessions.length; i++) {
if (sessions[i]!=null && !sessions[i].isValid()) {
expireHere++;
}
}
long timeEnd = System.currentTimeMillis();
if(log.isDebugEnabled())
log.debug("End expire sessions " + getName() + " processingTime " + (timeEnd - timeNow) + " expired sessions: " + expireHere);
processingTime += ( timeEnd - timeNow ); }
//添加session
public void add(Session session) { sessions.put(session.getIdInternal(), session);
int size = getActiveSessions();
if( size > maxActive ) {
synchronized(maxActiveUpdateLock) {
if( size > maxActive ) {
maxActive = size;
}
}
}
}

5.StandardManager实现了Manager接口,实现了session可持久化。

protected String pathname = "SESSIONS.ser";//session持久化的文件
//修改
public void setPathname(String pathname) { String oldPathname = this.pathname;
this.pathname = pathname;
//触发属性修改监听
support.firePropertyChange("pathname", oldPathname, this.pathname); }

6.Store用于存储session和用户数据

/*
Save the specified Session into this Store. Any previously saved
* information for the associated session identifier is replaced.
*/
public void save(Session session) throws IOException;
/**
* Remove all Sessions from this Store.
*/
public void clear() throws IOException;
public Session load(String id)
throws ClassNotFoundException, IOException;

总结:tomcat使用监听的事件比较多,对一些属性的修改都进行了监听,使用的非常巧妙。

Tomcat学习笔记(九)的更多相关文章

  1. 多线程学习笔记九之ThreadLocal

    目录 多线程学习笔记九之ThreadLocal 简介 类结构 源码分析 ThreadLocalMap set(T value) get() remove() 为什么ThreadLocalMap的键是W ...

  2. MDX导航结构层次:《Microsoft SQL Server 2008 MDX Step by Step》学习笔记九

    <Microsoft SQL Server 2008 MDX Step by Step>学习笔记九:导航结构层次   SQL Server 2008中SQL应用系列及BI笔记系列--目录索 ...

  3. python3.4学习笔记(九) Python GUI桌面应用开发工具选择

    python3.4学习笔记(九) Python GUI桌面应用开发工具选择 Python GUI开发工具选择 - WEB开发者http://www.admin10000.com/document/96 ...

  4. Go语言学习笔记九: 指针

    Go语言学习笔记九: 指针 指针的概念是当时学C语言时了解的.Go语言的指针感觉与C语言的没啥不同. 指针定义与使用 指针变量是保存内存地址的变量.其他变量保存的是数值,而指针变量保存的是内存地址.这 ...

  5. go微服务框架kratos学习笔记九(kratos 全链路追踪 zipkin)

    目录 go微服务框架kratos学习笔记九(kratos 全链路追踪 zipkin) zipkin使用demo 数据持久化 go微服务框架kratos学习笔记九(kratos 全链路追踪 zipkin ...

  6. Python学习笔记九

    Python学习笔记之九 为什么要有操作系统 管理硬件,提供接口. 管理调度进程,并且将多个进程对硬件的竞争变得有序. 操作系统发展史 第一代计算机:真空管和穿孔卡片 没有操作系统,所有的程序设计直接 ...

  7. vue学习笔记(九)vue-cli中的组件通信

    前言 在上一篇博客vue学习笔记(八)组件校验&通信中,我们学会了vue中组件的校验和父组件向子组件传递信息以及子组件通知父组件(父子组件通信),上一篇博客也提到那是对组件内容的刚刚开始,而本 ...

  8. C#线程学习笔记九:async & await入门二

    一.异步方法返回类型 只能返回3种类型(void.Task和Task<T>). 1.1.void返回类型:调用方法执行异步方法,但又不需要做进一步的交互. class Program { ...

  9. java jvm学习笔记九(策略文件)

    欢迎装载请说明出处:http://blog.csdn.net/yfqnihao/article/details/8271407 课程源码:http://download.csdn.net/detail ...

随机推荐

  1. 基于centos7实现的ftp

    前言 FTP(File transfer Protocl),文件传输协议,用于在网络上进行文件传输的一套标准协议,使用客户/服务器模式,属于网络传输协议的应用层.FTP服务运行在TCP/21和20端口 ...

  2. Yii2实现跨mysql数据库关联查询排序功能

    遇到一个项目,需要跨表网上找了很多的资料,整理一下,方便以后再次使用 背景:在一个mysql服务器上(注意:两个数据库必须在同一个mysql服务器上)有两个数据库: memory (存储常规数据表) ...

  3. 获取点击li的当前索引

    获取点击li的当前索引 点击特定次序的li  展现特定的页面 $('.wgsb').find('.wangge_data_list li').click(function(){ var index=$ ...

  4. 在ubuntu上安装subline

    Sublime Text is a most popular, lightweight and smart cross-platform text and source code editor wit ...

  5. 多线程之ReadWriteLock模拟缓存(九)

    错误案例1: package com.net.thread.lock; import java.util.HashMap; import java.util.Map; import java.util ...

  6. ORA-01122: 数据库文件 1 验证失败

    1.SQL>shutdown abort 如果数据库是打开状态,强行关闭 2.SQL>sqlplus / as sysdba 3.SQL>startupORACLE 例程已经启动. ...

  7. RHCSA考试

      RHCSA_PDF版传送门:https://files.cnblogs.com/files/zhangjianghua/RHCSA%E8%AF%95%E9%A2%98.pdf RHCE_PDF版传 ...

  8. Android Stadio 导入moudle 不显示

    Android Stadio 导入moudle 不显示,moudle 里面的java类也没有识别,只当是普通的txt文件. 后来,我发现,每个moudle 都有一个.iml 文件~ 然后我就随便翻翻配 ...

  9. android stadio open recent 在同一窗口打开

    Android staido 有一个功能是open recent ,默认是下面这样的: 就出来一个框,给你选择,是在新的窗口打开,还是在当前窗口打开.如果你选了当前窗口,并且点了Remember,do ...

  10. jQuery上传文件控件Uploadify使用

    Uploadify是JQuery的一个上传插件,支持ajax无刷新上传,多个文件同时上传,上传进行进度显示,删除已上传文件等. 首先应下载jQuery和uploadify插件 jQuery下载地址:h ...