Catalina通过一个叫管理器的组建来完成Session的管理。该管理器由一个接口Interface表示。
一个管理器通常和一个上下文容器相互管理,它负责创建,更新以及销毁session对象并给
任何请求组件返回一个合法的session.
一个servlet可以使用getSession方法获得一个session对象,该方法在javax.servlet.http.HttpServletRequest定义
它在默认连接器里由org.apache.catalina.connector.HttpRequestBase类实现
public HttpSession getSession() { return (getSession(true)); } public HttpSession getSession(boolean create) { .... return doGetSession(create); } private HttpSession doGetSession(boolean create) { if (context == null) return (null); if ((session != null) && !session.isValid()) session = null; if (session != null) return (session.getSession()); Manager manager = null; if (context != null) manager = context.getManager(); if (manager == null) return (null); if (requestedSessionId != null) { try { session = manager.findSession(requestedSessionId); }catch (IOException e) { session = null; } if ((session != null) && !session.isValid()) session = null; if (session != null) { return (session.getSession()); } } if (!create) return (null); if (session != null) return (session.getSession()); else return (null); }
默认情况下管理器将session对象存储在内存中,但是Tomcat也允许将session对象存储在文件或者数据库中(通过JDBC)
Sessions
在servlet编程中,一个session对象使用javax.servlet.http.HttpSession接口表示。该接口的标准实现是StandardSession类
由于一个Session对象常常被一个管理器持有,所以接口提供了setManager和getManager方法来关联一个Session对象和一个管理器
一个Session实例在跟管理器相关联的容器有一个唯一的ID。
StandardSession类
StandardSession类是Session接口的标准是实现。
实现了javax.servlet.http.HttpSession 和org.apache.catalina.Session之外,
它还实现了java.lang.Serializable接口来使得Session对象可序列化。
接下来是几个重要的变量在存放Session状态。注意transient使得该关键字不可序列化。
private HashMap attributes = new HashMap();
private transient String authType = null;
private transient boolean expiring = false;
private transient StandardSessionFacade facade = null;
一个Session对象如果在由maxInactiveInterval变量的时间内没有被进入则被终结。
使用Session接口中定义的expire方法可以终结一个Session对象
public void expire(boolean notify) { // Mark this session as "being expired" if needed if (expiring) return; expiring = true; setValid(false); // Remove this session from our manager's active sessions if (manager != null) manager.remove(this); // Unbind any objects associated with this session String keys[] = keys(); for (int i = 0; i < keys.length; i++) removeAttribute(keys[i], notify); // Notify interested session event listeners if (notify) { fireSessionEvent(Session.SESSION_DESTROYED_EVENT, null); } // Notify interested application event listeners // FIXME - Assumes we call listeners in reverse order Context context = (Context) manager.getContainer(); Object listeners[] = context.getApplicationListeners(); 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) { ; } // FIXME - should we do anything besides log these? log(sm.getString("standardSession.sessionEvent"), t); } } } // We have completed expire of this session expiring = false; if ((manager != null) && (manager instanceof ManagerBase)) { recycle(); } }
管理器
管理器用来管理Session对象
管理器由org.apache.catalina.Manager接口表示
ManagerBase类有两个直接子类:StandardManager和PersistentManagerBase类。
在运行的时候,StandardManager将session对象存放在内存中。
但是,当停止的时候,它将Session对象存放到文件中。当它再次启动的时候,重新载入Session对象。
PersistentManagerBase类作为一个管理器组件将Session对象存放到二级存储器中。
它有两个直接子类:PersistentManager和DistributedManager类