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使用监听的事件比较多,对一些属性的修改都进行了监听,使用的非常巧妙。

原文地址:https://www.cnblogs.com/lzeffort/p/7092377.html