Spring session life cycle

Spring session life cycle

spring session life cycle

Session acquisition

spring-session implements a subclass of HttpServletRequest – SessionRepositoryRequestWrapper, which overrides the getSession method and takes over the logic handled by the web container.




public HttpSession getSession(boolean create) {
            HttpSessionWrapper currentSession = getCurrentSession();
            if(currentSession != null) {
                return currentSession;
            }
            String requestedSessionId = getRequestedSessionId();
            if(requestedSessionId != null) {
                S session = sessionRepository.getSession(requestedSessionId);
                if(session != null) {
                    this.requestedSessionIdValid = true;
                    currentSession = new HttpSessionWrapper(session, getServletContext());
                    //从数据仓库提取出来的session状态不为new
                    currentSession.setNew(false);
                    setCurrentSession(currentSession);
                    return currentSession;
                }
            }
            if(!create) {
                return null;
            }
            S session = sessionRepository.createSession();
            currentSession = new HttpSessionWrapper(session, getServletContext());
            setCurrentSession(currentSession);
            return currentSession;
        }

When the session id exists, if the persistent session can be found through the session id, it will be returned directly, otherwise, it will be decided whether to create a new session according to whether create is true. Session will be changed successively in subsequent use, adding, deleting or modifying attribute values. The session extracted from the data warehouse will modify the lastAccessTime property by default to avoid session invalidation.

The persistent session in the data warehouse also has an expiration time. The consumer can set it through RedisHttpSessionConfiguration.setMaxInactiveIntervalInSeconds(long timemills). The default is 1800 seconds. Redis will periodically clear expired data.

Session implementation of spring-session

In order to separate the Session from the specific protocol, Spring extracts the Session entity separately, and then wraps the session through the HttpSessionWrapper to extend the HttpSession. If you need to support another application protocol in the future, you only need to add an application type wrapper. .

private final class HttpSessionWrapper implements HttpSession {

            public HttpSessionWrapper(S session, ServletContext servletContext) {
                this.session = session;
                this.servletContext = servletContext;
            }
            //省略了大部分方法,都是委托给被包装的Session处理的

            //对session坐invalidate时去数据仓库删掉对应的数据
            public void invalidate() {
                checkState();
                this.invalidated = true;
                requestedSessionInvalidated = true;
                setCurrentSession(null);
                sessionRepository.delete(getId());
            }

            public void setNew(boolean isNew) {
                this.old = !isNew;
            }

            public boolean isNew() {
                checkState();
                return !old;
            }
        }
    }

The Session entity mainly defines common methods such as getAttribute and setAttribute. In addition, an ExpiringSession is extended, which is the default session of spring, which is mainly used to determine whether the session is invalid.

public interface ExpiringSession extends Session {


    //session的创建时间
    long getCreationTime();


    //session的上次访问时间
    long getLastAccessedTime();


    //设置最大访问间隔,超过这个间隔session会被invalidate
    void setMaxInactiveIntervalInSeconds(int interval);

    int getMaxInactiveIntervalInSeconds();


    //session是否失效
    boolean isExpired();

}

session submission

        private void commitSession() {
            HttpSessionWrapper wrappedSession = getCurrentSession();
            if(wrappedSession == null) {
                if(isInvalidateClientSession()) {
                    httpSessionStrategy.onInvalidateSession(this, response);
                }
            } else {
                S session = wrappedSession.session;
                sessionRepository.save(session);
                if(!isRequestedSessionIdValid() || !session.getId().equals(getRequestedSessionId())) {
                    httpSessionStrategy.onNewSession(session, this, response);
                }
            }
        }
  1. When getSession, the newly created or extracted session will be placed on the HttpServletRequestWrapper.class.getName() attribute of the request through setCurrentSession; correspondingly, the session will also be removed from the request when the session is invalidated. to the data.
  2. When doing session persistence, it will first determine whether the session is invalidated, and if so, it will be deleted

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326600247&siteId=291194637