shiro源码篇-shiro的ssion的查询、刷新、过期与删除,你值得拥有

更新时间:2023-07-16 23:41:59 阅读: 评论:0

shiro源码篇-shiro的ssion的查询、刷新、过期与删除,你值得拥有
holly开⼼⼀刻 
  ⽼公酷爱⽹络游戏,⽼婆⽆奈,只得告诫他:你玩就玩了,但是千万不可以在游戏⾥找⽼婆,不然,哼哼。。。
  ⽼公嘴⾓露出了微笑:放⼼吧亲爱的,我绝对不会在游戏⾥找⽼婆的!因为我有⽼公!
  ⽼婆:......
前情回顾
  ⼤家还记得讲了什么吗,我们来⼀起简单回顾下:
    SecurityManager是shiro的核⼼,负责与shiro的其他组件进⾏交互;SessionManager是ssion的真正管理者,负责shiro的ssion管理;
    SessionsSecurityManager的start⽅法中将ssion的创建委托给了具体的ssionManager,是创建ssion的关键⼊⼝。
    SimpleSession是shiro完完全全的⾃⼰实现,是shiro对ssion的⼀种拓展;实现了ValidatingSession接⼝,具有⾃我校验的功能;⼀般不对外暴露,暴露的往往是他的代理:DelegatingSession;SimpleSession有⼏个属性值得重点关注下,如下
        id:就是ssion id;
        startTimestamp:ssion的创建时间;
        stopTimestamp:ssion的失效时间;
        lastAccessTime:ssion的最近⼀次访问时间,初始值是startTimestamp
        timeout:ssion的有效时长,默认30分钟
        expired:ssion是否到期
        attributes:ssion的属性容器
查询
  ssion的创建完成后,会将ssion(SimpleSession类型)对象的代理对象(DelegatingSession)
装饰成StoppingAwareProxiedSession对象,然后绑定到subject(类型是DelegatingSubject);
  Session ssion = Session();返回的就是绑定在当前subjuct的ssion。注意subject的实际类型是:DelegatingSubject,如下图
刷新
water pollution  shiro的Session接⼝提供了⼀个touch⽅法,负责ssion的刷新;ssion的代理对象最终会调⽤SimpleSession的touch():
public void touch() {
this.lastAccessTime = new Date();        // 更新最后被访问时间为当前时间
荛花
}
  但是touch⽅法是什么时候被调⽤的呢?JavaSE需要我们⾃⼰定期的调⽤ssion的touch() 去更新最后访问时间;如果是Web应⽤,每次进⼊ShiroFilter都会⾃动调⽤uch()来更新最后访问时间,ShiroFilter的类图如下:
  ShiroFilter⾃动调⽤uch()如下
西安美容培训
过期
  如果是让我们⾃⼰实现ssion过期的判断,我们会怎么做了?我们来看看shiro是怎么做的,或许我们能够从中学到⼀些经验。
韩语转换器
    还记得AbstractValidatingSessionManager中createSession⽅法吗?在调⽤doCreateSession⽅法之前调⽤
enableSessionValidationIfNecessary(),enableSessionValidationIfNecessary代码如下
private void enableSessionValidationIfNecessary() {
// 获取ssion验证调度器
SessionValidationScheduler scheduler = getSessionValidationScheduler();
// ssion验证调度器开启 && (调度器为空或调度器不可⽤)
马丁路德金简介if (isSessionValidationSchedulerEnabled() && (scheduler == null || !scheduler.isEnabled())) {
enableSessionValidation();        // 开启ssion验证
}
}
View Code
thought怎么读    第⼀次创建ssion的时候,如果ssion验证调度器启⽤(默认是启⽤),那么调⽤enableSessionValidation(),enableSessionValidation代码如下
protected synchronized void enableSessionValidation() {
SessionValidationScheduler scheduler = getSessionValidationScheduler();        // 获取调取器
if (scheduler == null) {
scheduler = createSessionValidationScheduler();                            // 创建调取器,实际类型是ExecutorServiceSessionValidationScheduler
tSessionValidationScheduler(scheduler);                                // 将调度器绑定到ssionManager
}
// it is possible that that a scheduler was already created and t via 'tSessionValidationScheduler()'
// but would not have been enabled/started yet
if (!scheduler.isEnabled()) {
if (log.isInfoEnabled()) {
log.info("Enabling ssion ");
}
afterSessionValidationEnabled();                                        // 什么也没做,供继承,便于拓展
}
}
View Code
    ExecutorServiceSessionValidationScheduler类图如下,它实现了Runnable接⼝
  调⽤scheduler的enableSessionValidation(),enableSessionValidation⽅法如下
public void enableSessionValidation() {
if (this.interval > 0l) {
换算英文// 创建ScheduledExecutorService
this.rvice = wSingleThreadScheduledExecutor(new ThreadFactory() {
private final AtomicInteger count = new AtomicInteger(1);
public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
thread.tDaemon(true);
thread.tName(threadNamePrefix + AndIncrement());
return thread;
}
});
/
/  初始化rvice interval时长之后开始执⾏this的run⽅法,每隔interval执⾏⼀次;注意interval的单位是TimeUnit.MILLISECONDS
this.rvice.scheduleAtFixedRate(this, interval, interval, TimeUnit.MILLISECONDS);    // this就是ExecutorServiceSessionValidationScheduler⾃⼰
}
}
View Code
  定时(默认每隔60分钟)的调⽤ExecutorServiceSessionValidationScheduler的run⽅法,run⽅法中调⽤ssionManager的validateSessions⽅法来完成ssion的验证,validateSessions⽅法如下
/
**
* @e ValidatingSessionManager#validateSessions()
*/
public void validateSessions() {
if (log.isInfoEnabled()) {
log.info("Validating all ");
}
int invalidCount = 0;
// 从ssionDao中获取全部的ssion
// ssionDao可以是默认的MemorySessionDAO,也可以是我们定制的CachingSessionDAO
Collection<Session> activeSessions = getActiveSessions();
if (activeSessions != null && !activeSessions.isEmpty()) {
// ⼀个⼀个校验
for (Session s : activeSessions) {
try {
//simulate a lookup key to satisfy the method signature.
//this could probably stand to be cleaned up in future versions:
SessionKey key = new Id());
validate(s, key);        // 真正校验的⽅法
} catch (InvalidSessionException e) {
if (log.isDebugEnabled()) {
boolean expired = (e instanceof ExpiredSessionException);
String msg = "Invalidated ssion with id [" + s.getId() + "]" +
(expired ? " (expired)" : " (stopped)");
log.debug(msg);
}
invalidCount++;            // 统计上次到这次定时任务间隔内过期的ssion个数
}
}
}
if (log.isInfoEnabled()) {
String msg = "Finished ssion validation.";
if (invalidCount > 0) {
msg += "  [" + invalidCount + "] ssions were stopped.";
} el {
msg += "  No ssions were stopped.";
}
log.info(msg);
}
}
View Code
  validate⽅法如下
protected void validate(Session ssion, SessionKey key) throws InvalidSessionException {
try {
doValidate(ssion);                    // 真正校验ssion
} catch (ExpiredSessionException e) {
彪炳什么意思onExpiration(ssion, e, key);        // 从ssionDao中删除过期的ssion
throw e;                                // 抛出异常供上层统计⽤
} catch (InvalidSessionException i) {
onInvalidation(ssion, i, key);        // 从ssionDao中删除不合法的ssion
throw i;                                // 抛出异常供上层统计⽤
}
}
View Code
  通过捕获doValidate()抛出的异常来剔除过期的或不合法的ssion,并将异常接着往上抛,供上层统计过期数量。注意:ExpiredSessionException的⽗类是StoppedSessionException,⽽StoppedSessionException的⽗类是InvalidSessionException。
  doValidate⽅法如下
protected void doValidate(Session ssion) throws InvalidSessionException {
if (ssion instanceof ValidatingSession) {
((ValidatingSession) ssion).validate();        // 校验ssion是否过期
} el {                                            // 若ssion不是ValidatingSession类型,则抛出IllegalStateException异常
String msg = "The " + getClass().getName() + " implementation only supports validating " +
"Session implementations of the " + Name() + " interface.  " +
"Plea either implement this interface in your ssion implementation or override the " +
Name() + ".doValidate(Session) method to perform validation.";
throw new IllegalStateException(msg);
primer}
}
View Code
    若ssion不是ValidatingSession类型,则抛出IllegalStateException异常
  validate⽅法如下

本文发布于:2023-07-16 23:41:59,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/78/1100421.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:验证   时间   创建   类型   对象   校验   调度
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图