Tomcat学习笔记(九)
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学习笔记(九)的更多相关文章
- 多线程学习笔记九之ThreadLocal
目录 多线程学习笔记九之ThreadLocal 简介 类结构 源码分析 ThreadLocalMap set(T value) get() remove() 为什么ThreadLocalMap的键是W ...
- MDX导航结构层次:《Microsoft SQL Server 2008 MDX Step by Step》学习笔记九
<Microsoft SQL Server 2008 MDX Step by Step>学习笔记九:导航结构层次 SQL Server 2008中SQL应用系列及BI笔记系列--目录索 ...
- python3.4学习笔记(九) Python GUI桌面应用开发工具选择
python3.4学习笔记(九) Python GUI桌面应用开发工具选择 Python GUI开发工具选择 - WEB开发者http://www.admin10000.com/document/96 ...
- Go语言学习笔记九: 指针
Go语言学习笔记九: 指针 指针的概念是当时学C语言时了解的.Go语言的指针感觉与C语言的没啥不同. 指针定义与使用 指针变量是保存内存地址的变量.其他变量保存的是数值,而指针变量保存的是内存地址.这 ...
- go微服务框架kratos学习笔记九(kratos 全链路追踪 zipkin)
目录 go微服务框架kratos学习笔记九(kratos 全链路追踪 zipkin) zipkin使用demo 数据持久化 go微服务框架kratos学习笔记九(kratos 全链路追踪 zipkin ...
- Python学习笔记九
Python学习笔记之九 为什么要有操作系统 管理硬件,提供接口. 管理调度进程,并且将多个进程对硬件的竞争变得有序. 操作系统发展史 第一代计算机:真空管和穿孔卡片 没有操作系统,所有的程序设计直接 ...
- vue学习笔记(九)vue-cli中的组件通信
前言 在上一篇博客vue学习笔记(八)组件校验&通信中,我们学会了vue中组件的校验和父组件向子组件传递信息以及子组件通知父组件(父子组件通信),上一篇博客也提到那是对组件内容的刚刚开始,而本 ...
- C#线程学习笔记九:async & await入门二
一.异步方法返回类型 只能返回3种类型(void.Task和Task<T>). 1.1.void返回类型:调用方法执行异步方法,但又不需要做进一步的交互. class Program { ...
- java jvm学习笔记九(策略文件)
欢迎装载请说明出处:http://blog.csdn.net/yfqnihao/article/details/8271407 课程源码:http://download.csdn.net/detail ...
随机推荐
- js动画之无缝滚动
效果图如下: HTML代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charse ...
- LVS基于NAT模式搭建负载均衡群集
LVS的基本架构图 负载均衡群集中,包括三个层次的组件: 1.第一层,负载调度器(BL) 前段至少有一个负载调度器(Load Balancer 或称为Director)负责响应并分发来自客户端的访问请 ...
- ELK之Elasticsearch
安装并运行Elasetisearch cd elasticsearch-<version> ./bin/elasticsearch 如果你想把 Elasticsearch 作为一个守护进程 ...
- ST-LINK JLINK JTAG SWD接线图
- 非阻塞IO模板
服务端 from socke import * server = socket(AF_INET, SOCK_STREAM) server.bind(('127.0.0.1',8083)) server ...
- [转]Android进程间通信--消息机制及IPC机制实现
Android为了屏蔽进程的概念,利用不同的组件[Activity.Service]来表示进程之间的通信! 组件间通信的核心机制是Intent,通过Intent可以开启一个Activity或Servi ...
- 导出csv用excel打开后数字不用科学计数法显示(0123456显示123456)
从这儿抄过来的: http://zhejiangyinghui.iteye.com/blog/1149526 最近写了一个生成csv的程序,生成的csv其中有一列数字长度为13位,csv中查看没有问题 ...
- 图解-Excel的csv格式特殊字符处理方式尝试笔记(个人拙笔)
Excel格式如下.(截图来自,WPS Office) CSV是一种文本格式的Excel文档格式.不支持Excel的字体特效(比如加粗,颜色)等等的保存. 每一行数据用 "\n" ...
- Java中Set的contains()方法——hashCode与equals方法的约定及重写原则
转自:http://blog.csdn.net/renfufei/article/details/14163329 翻译人员: 铁锚 翻译时间: 2013年11月5日 原文链接: Java hashC ...
- Python 3基础教程1-环境安装和运行环境
本系列开始介绍Python3的基础教程,为什么要选中Python 3呢?之前呢,学Python 2,看过笨方法学Python,学了不到一个礼拜,就开始用Python写Selenium脚本.最近看到一些 ...