AbstractValidatingSessionManager具體實現了ValidatingSessionManager的行爲,覆蓋AbstractNativeSessionManager的行爲,定義抽象行爲java
具有了SessionValidationScheduler(Session校驗任務調度器,set注入方式)、sessionValidationSchedulerEnabled(Session校驗任務調度器開關,set注入方式,默認開啓);session
// 若是有必要的話開啓Session校驗 private void enableSessionValidationIfNecessary() { SessionValidationScheduler scheduler = getSessionValidationScheduler(); // Session校驗開關開啓而且Session校驗任務調度器爲空或者是不可用 if (isSessionValidationSchedulerEnabled() && (scheduler == null || !scheduler.isEnabled())) { // 開啓Session校驗 enableSessionValidation(); } }
開啓Session校驗ide
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() { }
書接前文#1this
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; }
書接前文#2atom
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."); } }
校驗全部有效的Sessionspa
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();
具體的校驗任務debug
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); } }