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

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

类结构如下:

理解 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来查找谁调用了
ExecutorServiceSessionValidationSchedule的enableSessionValidation()方法。
AbstractVailidatingSessionManager 中 enableSessionValidation()
该方法调用了 SessionValidationScheduler的 enableSessionValidation;
而它自己又被本类中的 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 | |
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 | } |