Shiro Session及SessionManager的设计概念
涉及的SessionManager
AbstractNativeSessionManager:Session管理器具备创建和查询Session的行为,但是其本身没有这些具体的职能,只能抽象化,由其子类具体执行
DefaultSessionManager:默认的Session管理器具备了SessionFactory和SessionDao,拥有创建和查询Session的具体职能
涉及的Session
DelegatingSession:Session委派者具备了Session管理器和SessionKey,本身不具备获得Session具体属性的职能,只能交由Session管理器执行
SimpleSession:基础Session拥有Session的各种属性
AbstractNativeSessionManager创建Session
public Session start(SessionContext context) { // 创建SimpleSession Session session = createSession(context); applyGlobalSessionTimeout(session); onStart(session, context); notifyStart(session); // 包装Session为DelegatingSession return createExposedSession(session, context); }
将AbstractNativeSessionManager和SessionKey注入到DelegatingSession中
protected Session createExposedSession(Session session, SessionContext context) { return new DelegatingSession(this, new DefaultSessionKey(session.getId())); }
DelegatingSession的构造函数
private final SessionKey key; private final transient NativeSessionManager sessionManager; public DelegatingSession(NativeSessionManager sessionManager, SessionKey key) { if (sessionManager == null) { throw new IllegalArgumentException("sessionManager argument cannot be null."); } if (key == null) { throw new IllegalArgumentException("sessionKey argument cannot be null."); } if (key.getSessionId() == null) { String msg = "The " + DelegatingSession.class.getName() + " implementation requires that the " + "SessionKey argument returns a non-null sessionId to support the " + "Session.getId() invocations."; throw new IllegalArgumentException(msg); } this.sessionManager = sessionManager; this.key = key; }
Session获得其属性如startTimestamp
通过注入进来的AbstractNativeSessionManager和SessionKey获得该属性值
public Date getStartTimestamp() { if (startTimestamp == null) { startTimestamp = sessionManager.getStartTimestamp(key); } return startTimestamp; }
从其他介质中获得Session(如Redis中),然后获得该Session的属性值
public Date getStartTimestamp(SessionKey key) { return lookupRequiredSession(key).getStartTimestamp(); }