Catalina 通过Manager接口支持会话管理,一个Manager与一个context关联,Manager负责创建 更新 销毁session对象,也返回合格的对象给请求组件。
Servlet可以通过调用ServletRequest 接口的getSession方法获得一个session。
我们看一下实现了这个接口的HttpRequestBase 类。
public HttpSession getSession() { return (getSession(true)); } public HttpSession getSession(boolean create) { ... return doGetSession(create); } private HttpSession doGetSession(boolean create) { // There cannot be a session if no context has been assigned yet if (context == null) return (null); // Return the current session if it exists and is valid if ((session != null) && !session.isValid()) session = null; if (session != null) return (session.getSession()); // Return the requested session if it exists and is valid Manager manager = null; if (context != null) manager = context.getManager(); if (manager == null) if (manager == null) return (null); // Sessions are not supported 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()); } } // Create a new session if requested and the resp // committed if (!create) return (null); ... session = manager.createSession(); if (session != null) return (session.getSession()); else return (null); }
默认,manager把它的session对象放在内存中,tomcat也允许manager通过jdbc持久化到数据库中。
Sessions
在servlet编程中,session代表HttpSession接口,这个接口的实现类StandardSession基于安全的考虑,manager不会传递它的实例给servlet,而是用StandardSessionFacade来代替。
session接口
Listing 9.1: The Session interface package org.apache.catalina; import java.io.IOException; import java.security.Principal; import java.util.Iterator; import javax.servlet.ServletException; import javax.servlet.http.HttpSession; public interface Session { public static final String SESSION_CREATED_EVENT = "createSession"; public static final String SESSION_DESTROYED_EVENT = "destroySession"; public String getAuthType(); public void setAuthType(String authType); public long getCreationTime(); public void setCreationTime(long time); public String getId(); public void setId(String id); public String getInfo(); public long getLastAccessedTime(); public Manager getManager(); public void setManager(Manager manager); public int getMaxInactiveInterval(); public void setMaxInactiveInterval(int interval); public void setNew(boolean isNew); public Principal getPrincipal(); public void setPrincipal(Principal principal); public HttpSession getSession(); public void setValid(boolean isValid); public boolean isValid(); public void access(); public void addSessionListener(SessionListener listener); public void expire(); public Object getNote(String name); public Iterator getNoteNames(); public void recycle(); public void removeNote(String name); public void removeSessionListener(SessionListener listener); public void setNote(String name, Object value); }一个session对象一定包含一个manager,在context中,session有唯一的标示联系到它的manager。
StandardSession类
The getSession 方法创建了一个StandardSessionFacade对象: @Override public HttpSession getSession() { if (facade == null){ if (SecurityUtil.isPackageProtectionEnabled()){ final StandardSession fsession = this; facade = AccessController.doPrivileged( new PrivilegedActionStandardManager类(){ @Override public StandardSessionFacade run(){ return new StandardSessionFacade(fsession); } }); } else { facade = new StandardSessionFacade(this); } } return (facade); }
Manager的标准实现,将session储存与内存中,实现了lifeCycle接口,它可以被启动和停止。