学习 准备 尝试 谨慎小心

0%

Shiro源码解析之SessionManager03-SessionValidationScheduler

了解 SessionValidationScheduler

SessionValidationScheduler 会话验证调度器,定时调用方法 validateSessions() 验证session是否过期。其实例n在 AbstractValidatingSessionManager 中被声明。

1571299072379

sessionManager 默认使 用ExecutorServiceSessionValidationSchedule,类继承图如下:

1571299161013

类结构如下:

1571298835647

理解 SessionValidationScheduler

enableSessionValidation(): void

ExecutorServiceSessionValidationScheduler 中的实现:

1
/**
2
     * Creates a single thread {@link ScheduledExecutorService} to validate sessions at fixed intervals 
3
     * and enables this scheduler. The executor is created as a daemon thread to allow JVM to shut down
4
     */
5
    //TODO Implement an integration test to test for jvm exit as part of the standalone example
6
    // (so we don't have to change the unit test execution model for the core module)
7
    public void enableSessionValidation() {
8
        if (this.interval > 0l) {
9
            // 真正的定时器
10
            this.service = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {  
11
	            private final AtomicInteger count = new AtomicInteger(1);
12
13
	            public Thread newThread(Runnable r) {  
14
	                Thread thread = new Thread(r);  
15
	                thread.setDaemon(true);  
16
	                thread.setName(threadNamePrefix + count.getAndIncrement());
17
	                return thread;  
18
	            }  
19
            });        
20
            // 启动定时器,看 `scheduleAtFixedRate` 源码注释理解该方法
21
            this.service.scheduleAtFixedRate(this, interval, interval, TimeUnit.MILLISECONDS);
22
        }
23
        this.enabled = true;
24
    }
25
26
    public void run() {
27
        if (log.isDebugEnabled()) {
28
            log.debug("Executing session validation...");
29
        }
30
        long startTime = System.currentTimeMillis();
31
        this.sessionManager.validateSessions();
32
        long stopTime = System.currentTimeMillis();
33
        if (log.isDebugEnabled()) {
34
            log.debug("Session validation completed successfully in " + (stopTime - startTime) + " milliseconds.");
35
        }
36
    }

简译:以固定的时间间隔创建一个单线程来验证会话,并且开启这个调度。
scheduleAtFixedRate() 方法第一个参数以 Runnable 实现对象,里面一定是调用了 Runnable 对象的 run()

那么,是在什么时候开启的定时器呢?

这时我使用 Alt+F7来查找调用了 ExecutorServiceSessionValidationScheduleenableSessionValidation() 方法。

AbstractVailidatingSessionManagerenableSessionValidation()

该方法调用了 SessionValidationSchedulerenableSessionValidation
而它自己又被本类中的 enableSessionValidationIfNecessary() 方法调用 ;
enableSessionValidationIfNecessary() 又被本类中的doGetSession()createSession()方法调用。

1
......
2
   // line 83    
3
private void enableSessionValidationIfNecessary() {
4
       SessionValidationScheduler scheduler = getSessionValidationScheduler();
5
       if (isSessionValidationSchedulerEnabled() && (scheduler == null || !scheduler.isEnabled())) {
6
           enableSessionValidation();
7
       }
8
   }
9
10
......
11
   // line 112
12
   @Override
13
   protected final Session doGetSession(final SessionKey key) throws InvalidSessionException {
14
       enableSessionValidationIfNecessary();
15
16
       log.trace("Attempting to retrieve session with key {}", key);
17
18
       Session s = retrieveSession(key);
19
       if (s != null) {
20
           validate(s, key);
21
       }
22
       return s;
23
   }
24
......
25
   // line 134
26
   protected Session createSession(SessionContext context) throws AuthorizationException {
27
       enableSessionValidationIfNecessary();
28
       return doCreateSession(context);
29
   }
30
......
31
   // line 223    
32
protected synchronized void enableSessionValidation() {
33
       SessionValidationScheduler scheduler = getSessionValidationScheduler();
34
       if (scheduler == null) {
35
           scheduler = createSessionValidationScheduler();
36
           setSessionValidationScheduler(scheduler);
37
       }
38
       // it is possible that that a scheduler was already created and set via 'setSessionValidationScheduler()'
39
       // but would not have been enabled/started yet
40
       if (!scheduler.isEnabled()) {
41
           if (log.isInfoEnabled()) {
42
               log.info("Enabling session validation scheduler...");
43
           }
44
           scheduler.enableSessionValidation();
45
           afterSessionValidationEnabled();
46
       }
47
   }