Shiro AbstractValidatingSessionManager设计概念

Posted Firm陈

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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);
    

以上是关于Shiro AbstractValidatingSessionManager设计概念的主要内容,如果未能解决你的问题,请参考以下文章

shiro教程- shiro介绍

Shiro-----Shiro认证

Shiro - Shiro简介;Shiro与Spring Security区别;Spring Boot集成Shiro

[shiro] - 怎样使用shiro?

每天学点Shiro-shiro标签

shiro学习笔记_0100_shiro简介