AbstractValidatingSessionManager具體實現了ValidatingSessionManager的行為,覆蓋AbstractNativeSessionManager的行為,定義抽象行為
具備了SessionValidationScheduler(Session校驗任務調度器,set注入方式)、sessionValidationSchedulerEnabled(Session校驗任務調度器開關,set注入方式,默認開啟);
// 如果有必要的話開啟Session校驗 private void enableSessionValidationIfNecessary() { SessionValidationScheduler scheduler = getSessionValidationScheduler(); // Session校驗開關開啟並且Session校驗任務調度器為空或者是不可用 if (isSessionValidationSchedulerEnabled() && (scheduler == null || !scheduler.isEnabled())) { // 開啟Session校驗 enableSessionValidation(); } }
開啟Session校驗
protected synchronized void enableSessionValidation() { SessionValidationScheduler scheduler = getSessionValidationScheduler(); if (scheduler == null) { // 創建Session校驗任務調度器,后文詳解#1 scheduler = createSessionValidationScheduler(); // 為AbstractValidatingSessionManager設置Session校驗任務調度器 setSessionValidationScheduler(scheduler); } // 可能Session校驗任務調度器已經被創建只不過還沒有啟用 if (!scheduler.isEnabled()) { if (log.isInfoEnabled()) { log.info("Enabling session validation scheduler..."); } // 啟用Session校驗任務調度器,后文詳解#2 scheduler.enableSessionValidation(); // 啟用Session校驗任務調度器后需要做的事情 afterSessionValidationEnabled(); } } // 一個空的方法,等待覆蓋 protected void afterSessionValidationEnabled() { }
書接前文#1
protected SessionValidationScheduler createSessionValidationScheduler() { ExecutorServiceSessionValidationScheduler scheduler; if (log.isDebugEnabled()) { log.debug("No sessionValidationScheduler set. Attempting to create default instance."); } // SessionValidationScheduler注入AbstractValidatingSessionManager scheduler = new ExecutorServiceSessionValidationScheduler(this); // 設置任務調度器的時間間隔,默認60分鍾 scheduler.setInterval(getSessionValidationInterval()); if (log.isTraceEnabled()) { log.trace("Created default SessionValidationScheduler instance of type [" + scheduler.getClass().getName() + "]."); } return scheduler; }
書接前文#2
import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; private ScheduledExecutorService service; public void enableSessionValidation() { if (this.interval > 0l) { this.service = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() { private final AtomicInteger count = new AtomicInteger(1); public Thread newThread(Runnable r) { Thread thread = new Thread(r); thread.setDaemon(true); thread.setName(threadNamePrefix + count.getAndIncrement()); return thread; } }); this.service.scheduleAtFixedRate(this, interval, interval, TimeUnit.MILLISECONDS); } this.enabled = true; } public void run() { if (log.isDebugEnabled()) { log.debug("Executing session validation..."); } long startTime = System.currentTimeMillis(); // ValidatingSessionManager執行校驗Session的任務 this.sessionManager.validateSessions(); long stopTime = System.currentTimeMillis(); if (log.isDebugEnabled()) { log.debug("Session validation completed successfully in " + (stopTime - startTime) + " milliseconds."); } }
校驗所有有效的Session
public void validateSessions() { if (log.isInfoEnabled()) { log.info("Validating all active sessions..."); } int invalidCount = 0; // 獲得所有有效的Session,從其他介質中獲得(如Redis) Collection<Session> activeSessions = getActiveSessions(); if (activeSessions != null && !activeSessions.isEmpty()) { for (Session s : activeSessions) { try { 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); } } // 空方法,AbstractValidatingSessionManager本身是沒有這個職能的只能交給子類去實現,待子類覆蓋 protected abstract Collection<Session> getActiveSessions();
具體的校驗任務
protected void validate(Session session, SessionKey key) throws InvalidSessionException { try { // Session為基礎Session:SimpleSession doValidate(session); } catch (ExpiredSessionException ese) { onExpiration(session, ese, key); throw ese; } catch (InvalidSessionException ise) { onInvalidation(session, ise, key); throw ise; } } protected void doValidate(Session session) throws InvalidSessionException { if (session instanceof ValidatingSession) { // 面向對象,只有Session自己能校驗自己是否過期了(類似於門把自己關上了) ((ValidatingSession) session).validate(); } else { String msg = "The " + getClass().getName() + " implementation only supports validating " + "Session implementations of the " + ValidatingSession.class.getName() + " interface. " + "Please either implement this interface in your session implementation or override the " + AbstractValidatingSessionManager.class.getName() + ".doValidate(Session) method to perform validation."; throw new IllegalStateException(msg); } }