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

目录 前言 前情回顾 查询 刷新 过期 启动校验定时任务 session校验 校验总结 删除 疑问 总结 参考 回到顶部 前言   开心一刻       老公酷爱网络游戏,老婆无奈,只得告诫他:你玩就玩了,但是千万不可以在游戏里找老婆,不然,哼哼。。。     老公嘴角露出了微笑:放心吧亲爱的,我绝对不会在游戏里找老婆的!因为我有老公!     老婆:......   路漫漫其修远兮,吾将上下而求索!   github:https://github.com/youzhibing   码云(gitee):https://gitee.com/youzhibing 回到顶部 前情回顾   大家还记得上篇博文讲了什么吗,我们来一起简单回顾下:     SecurityManager是shiro的核心,负责与shiro的其他组件进行交互;SessionManager是session的真正管理者,负责shiro的session管理;     SessionsSecurityManager的start方法中将session的创建委托给了具体的sessionManager,是创建session的关键入口。     SimpleSession是shiro完完全全的自己实现,是shiro对session的一种拓展;实现了ValidatingSession接口,具有自我校验的功能;一般不对外暴露,暴露的往往是他的代理:DelegatingSession;SimpleSession有几个属性值得重点关注下,如下         id:就是session id;         startTimestamp:session的创建时间;         stopTimestamp:session的失效时间;         lastAccessTime:session的最近一次访问时间,初始值是startTimestamp         timeout:session的有效时长,默认30分钟         expired:session是否到期         attributes:session的属性容器 回到顶部 查询   session的创建完成后,会将session(SimpleSession类型)对象的代理对象(DelegatingSession)装饰成StoppingAwareProxiedSession对象,然后绑定到subject(类型是DelegatingSubject);   Session session = subject.getSession();返回的就是绑定在当前subjuct的session。注意subject的实际类型是:DelegatingSubject,如下图 回到顶部 刷新   shiro的Session接口提供了一个touch方法,负责session的刷新;session的代理对象最终会调用SimpleSession的touch(): 复制代码 public void touch() { this.lastAccessTime = new Date(); // 更新最后被访问时间为当前时间 } 复制代码   但是touch方法是什么时候被调用的呢?JavaSE需要我们自己定期的调用session的touch() 去更新最后访问时间;如果是Web应用,每次进入ShiroFilter都会自动调用session.touch()来更新最后访问时间,ShiroFilter的类图如下:   ShiroFilter自动调用session.touch()如下 回到顶部 过期   如果是让我们自己实现session过期的判断,我们会怎么做了?我们来看看shiro是怎么做的,或许我们能够从中学到一些经验。   启动校验定时任务     还记得AbstractValidatingSessionManager中createSession方法吗?在调用doCreateSession方法之前调用enableSessionValidationIfNecessary(),enableSessionValidationIfNecessary代码如下 View Code     第一次创建session的时候,如果session验证调度器启用(默认是启用),那么调用enableSessionValidation(),enableSessionValidation代码如下 View Code     ExecutorServiceSessionValidationScheduler类图如下,它实现了Runnable接口   调用scheduler的enableSessionValidation(),enableSessionValidation方法如下 View Code   session校验   定时(默认每隔60分钟)的调用ExecutorServiceSessionValidationScheduler的run方法,run方法中调用sessionManager的validateSessions方法来完成session的验证,validateSessions方法如下 View Code   validate方法如下 View Code   通过捕获doValidate()抛出的异常来剔除过期的或不合法的session,并将异常接着往上抛,供上层统计过期数量。注意:ExpiredSessionException的父类是StoppedSessionException,而StoppedSessionException的父类是InvalidSessionException。   doValidate方法如下 View Code     若session不是ValidatingSession类型,则抛出IllegalStateException异常   validate方法如下 View Code   校验总结     1、sesion的有效时长默认30分钟;定时任务默认是每60分钟执行一次,第一次执行是在定时器初始化完成60分钟后执行;     2、session不是ValidatingSession类型,则抛出IllegalStateException异常;session已经停止了则抛出StoppedSessionException;session过期则抛出ExpiredSessionException异常;理论上来讲IllegalStateException与StoppedSessionException不会被抛出,应该全是ExpiredSessionException异常;ExpiredSessionException继承自StoppedSessionException,而StoppedSessionException又继承自IllegalStateException;     3、校验session的时候,抛出了异常,将其捕获,从sessionDao中删除对应的session,并使过期数量自增1 回到顶部 删除   夹杂在过期定时任务中,与过期是同时进行的,利用的异常机制;当然session操作的时候sessionManager也有session的校验,伴随着就有session的删除。 回到顶部 疑问   定时任务默认每60分钟执行一次,而session有效时长默认是30分钟,那么定时任务执行的间隔内肯定有session过期了,而我们在这个间隔内操作了过期的session怎么办?   其实这个问题应该这么来问:在定时任务间隔期间,对session的操作有没有做校验处理?答案是肯定的。   通过上面的讲解我们知道:session的操作通过代理之后,都会来到sessionManager,sessionManager通过处理之后再到SimpleSession;AbstractNativeSessionManager中将session操作放给SimpleSession之前,都会调用lookupSession方法,跟进lookupSession你会发现,里面也有session的校验。   所以session的校验,不只是定制任务在执行,很多session的操作都有做session的校验。 回到顶部 总结   1、一般我们操作subject是DelegatingSubject类型,DelegatingSubject中将subject的操作委托给了securityManager;一般操作的session是session的代理,代理将session操作委托给sessionManager,sesionManager校验之后再转交给SimpleSession;   2、session过期定时任务默认60分钟执行一次,所session已过期或不合法,则抛出对应的异常,上层通过捕获异常从sessionDao中删除session   3、不只定时任务做session的校验,session的基本操作都在sessionManager中有做session的校验 https://www.cnblogs.com/youzhibing/p/9810342.html
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信