zoukankan      html  css  js  c++  java
  • 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);
        }
    }
  • 相关阅读:
    给入门程序员的一些学习建议(一定要看)
    拦截器工作原理
    Struts 2中如何解决中文乱码问题?
    struts1与struts2的区别。
    MVC是什么?
    spring MVC工作原理
    C#中,子类构造函数调用父类父类构造函数的正确方式
    泛型的优点
    jsp的page、request、session、application四个作用域的作用
    jsp转发与重定向的区别
  • 原文地址:https://www.cnblogs.com/BINGJJFLY/p/9295017.html
Copyright © 2011-2022 走看看