(1)在DelegatingSubject类中可以获取Session:
1 public Session getSession(boolean create) { 2 ....... 3 SessionContext sessionContext = createSessionContext(); 4 Session session = this.securityManager.start(sessionContext); 5 this.session = decorate(session); 6 ....... 7 return this.session; 8 9 }
(2)SecurityManager委托sessionManager(DefaultSessionManage)处理Session的创建:
1 public Session start(SessionContext context) throws AuthorizationException { 2 return this.sessionManager.start(context); 3 }
*注意:DefaultSessionManage的内部架构为:
(3)AbstractNativeSessionManager创建Session并管理Session:
1 public Session start(SessionContext context) { 2 Session session = createSession(context); 3 applyGlobalSessionTimeout(session); 4 onStart(session, context); 5 notifyStart(session); 6 //Don't expose the EIS-tier Session object to the client-tier: 7 return createExposedSession(session, context); 8 }
(4)到此Session的创建完成,及细节代码如下:AbstractNativeSessionManager交给AbstractValidatingSessionManager处理:
1 protected Session createSession(SessionContext context) throws AuthorizationException { 2 enableSessionValidationIfNecessary(); 3 return doCreateSession(context); 4 } 5 // 6 private void enableSessionValidationIfNecessary() { 7 SessionValidationScheduler scheduler = getSessionValidationScheduler(); 8 if (isSessionValidationSchedulerEnabled() && (scheduler == null || !scheduler.isEnabled())) { 9 enableSessionValidation(); 10 } 11 } 12 // 13 protected void enableSessionValidation() { 14 SessionValidationScheduler scheduler = getSessionValidationScheduler(); 15 if (scheduler == null) { 16 scheduler = createSessionValidationScheduler();//scheduler = new ExecutorServiceSessionValidationScheduler(this);scheduler.setInterval(getSessionValidationInterval()); 17 setSessionValidationScheduler(scheduler); 18 } 19 if (log.isInfoEnabled()) { 20 log.info("Enabling session validation scheduler..."); 21 } 22 scheduler.enableSessionValidation(); 23 afterSessionValidationEnabled(); 24 } 25
(5)ExecutorServiceSessionValidationScheduler验证Session的过期:
1 /** 2 * Creates a single thread {@link ScheduledExecutorService} to validate sessions at fixed intervals 3 * and enables this scheduler. The executor is created as a daemon thread to allow JVM to shut down 4 */ 5 //TODO Implement an integration test to test for jvm exit as part of the standalone example 6 // (so we don't have to change the unit test execution model for the core module) 7 public void enableSessionValidation() { 8 if (this.interval > 0l) { 9 this.service = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() { 10 public Thread newThread(Runnable r) { 11 Thread thread = new Thread(r); 12 thread.setDaemon(true); 13 return thread; 14 } 15 }); 16 this.service.scheduleAtFixedRate(this, interval, interval, TimeUnit.MILLISECONDS); 17 this.enabled = true; 18 } 19 } 20 21 public void run() { 22 if (log.isDebugEnabled()) { 23 log.debug("Executing session validation..."); 24 } 25 long startTime = System.currentTimeMillis(); 26 this.sessionManager.validateSessions(); 27 long stopTime = System.currentTimeMillis(); 28 if (log.isDebugEnabled()) { 29 log.debug("Session validation completed successfully in " + (stopTime - startTime) + " milliseconds."); 30 } 31 }
(6)AbstractValidatingSessionManager验证Session的过期:
/** * @see ValidatingSessionManager#validateSessions() */ public void validateSessions() { if (log.isInfoEnabled()) { log.info("Validating all active sessions..."); } int invalidCount = 0; Collection<Session> activeSessions = getActiveSessions(); if (activeSessions != null && !activeSessions.isEmpty()) { for (Session s : activeSessions) { try { //simulate a lookup key to satisfy the method signature. //this could probably stand to be cleaned up in future versions: SessionKey key = new DefaultSessionKey(s.getId()); validate(s, key); } catch (InvalidSessionException e) { if (log.isDebugEnabled()) { boolean expired = (e instanceof ExpiredSessionException); String msg = "Invalidated session with id [" + s.getId() + "]" + (expired ? " (expired)" : " (stopped)"); log.debug(msg); } invalidCount++; } } } if (log.isInfoEnabled()) { String msg = "Finished session validation."; if (invalidCount > 0) { msg += " [" + invalidCount + "] sessions were stopped."; } else { msg += " No sessions were stopped."; } log.info(msg); } } //类DefaultSessionManager实现getActiveSessions接口 protected abstract Collection<Session> getActiveSessions(); protected Collection<Session> getActiveSessions() { Collection<Session> active = sessionDAO.getActiveSessions(); return active != null ? active : Collections.<Session>emptySet(); }
(7)Session的校验完成,接下来是DefaultSessionManager进行Session的创建:
protected Session doCreateSession(SessionContext context) { Session s = newSessionInstance(context); if (log.isTraceEnabled()) { log.trace("Creating session for host {}", s.getHost()); } create(s); return s; }
protected Session newSessionInstance(SessionContext context) {
return getSessionFactory().createSession(context);
}
protected void create(Session session) {
if (log.isDebugEnabled()) {
log.debug("Creating new EIS record for new session instance [" + session + "]");
}
sessionDAO.create(session);
}
(8)DefaultSessionManager委托Session(MemorySessionDAO)维护Session:
1 protected Serializable doCreate(Session session) { 2 Serializable sessionId = generateSessionId(session); 3 assignSessionId(session, sessionId); 4 storeSession(sessionId, session); 5 return sessionId; 6 }
protected Session storeSession(Serializable id, Session session) {
if (id == null) {
throw new NullPointerException("id argument cannot be null.");
}
return sessions.putIfAbsent(id, session);
}
(9) 创建并维护Session之后,AbstractNativeSessionManager交给注册好的监听器,监听器调用启动onStart接口
1 protected void notifyStart(Session session) { 2 for (SessionListener listener : this.listeners) { 3 listener.onStart(session); 4 } 5 }
(10)最后创建委托Session,
protected Session createExposedSession(Session session, SessionContext context) { return new DelegatingSession(this, new DefaultSessionKey(session.getId())); }
(11)最后Subject创建自己的代理Session,主要用来拦截stop方法:
1 protected Session decorate(Session session) { 2 if (session == null) { 3 throw new IllegalArgumentException("session cannot be null"); 4 } 5 return new StoppingAwareProxiedSession(session, this); 6 } 7 private class StoppingAwareProxiedSession extends ProxiedSession { 8 9 private final DelegatingSubject owner; 10 11 private StoppingAwareProxiedSession(Session target, DelegatingSubject owningSubject) { 12 super(target); 13 owner = owningSubject; 14 } 15 16 public void stop() throws InvalidSessionException { 17 super.stop(); 18 owner.sessionStopped(); 19 } 20 }
总结: