Shiro AbstractValidatingSessionManager設計概念


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);
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM