加入收藏 | 设为首页 | 会员中心 | 我要投稿 泉州站长网 (https://www.0595zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长资讯 > 传媒 > 正文

异步线程获取不到Session问题

发布时间:2021-04-12 17:29:44 所属栏目:传媒 来源:互联网
导读:在服务端接收到客户端请求时,如果客户端有带上Session ID,那么就根据Session ID获取Session,默认是从内存获取,如果是使用Shiro框架并且使用Redis存储Session,那么就是从Redis中获




在服务端接收到客户端请求时,如果客户端有带上Session ID,那么就根据Session ID获取Session,默认是从内存获取,如果是使用Shiro框架并且使用Redis存储Session,那么就是从Redis中获取。

如果Session过期或者客户端没有传递Session ID,则创建新的Session,并会为新的Session重新分配Session ID。

Shrio框架在接收到请求时就通过过滤器拿到Session ID存储到ThreadLocal中了,所以不需要通过HttpServletRequest去拿Session。

Shrio之所以支持在异步线程中还能够获取到Session,这其实是因为Shrio使用的是InheritableThreadLocal,而不是ThreadLocal,实现了将Session ID传递给子线程,因此实现了“异步上下文”传递Session。

但这也是有局限的,要求这个异步线程必须是由当前处理请求的线程创建的,Session ID才能通过InheritableThreadLocal传递给子线程,如果是在线程池中,就不一定能获取到了。

这里留个思考题给大家:为什么说在线程池中不一定能获取到,而不是一定获取不到?要理解这个问题需要对线程池的工作原理、源码,以及InheritableThreadLocal源码理解,因此本篇不展开分析。

所以我们解决Bug就是将ThreadLocal换成InheritableThreadLocal,并且通过方法拦截器(HandlerInterceptor)或者过滤器(Filter)实现set session和remove session操作,推荐后者。

另外,从webmcv框架源码可以看出,RequestContextHolder#getRequestAttributes也是支持InheritableThreadLocal的,只是默认情况下不支持,需要修改配置。

getRequestAttributes方法会尝试从InheritableThreadLocal获取,源码如下。

在服务端接收到客户端请求时,如果客户端有带上Session ID,那么就根据Session ID获取Session,默认是从内存获取,如果是使用Shiro框架并且使用Redis存储Session,那么就是从Redis中获取。

如果Session过期或者客户端没有传递Session ID,则创建新的Session,并会为新的Session重新分配Session ID。

Shrio框架在接收到请求时就通过过滤器拿到Session ID存储到ThreadLocal中了,所以不需要通过HttpServletRequest去拿Session。

Shrio之所以支持在异步线程中还能够获取到Session,这其实是因为Shrio使用的是InheritableThreadLocal,而不是ThreadLocal,实现了将Session ID传递给子线程,因此实现了“异步上下文”传递Session。

但这也是有局限的,要求这个异步线程必须是由当前处理请求的线程创建的,Session ID才能通过InheritableThreadLocal传递给子线程,如果是在线程池中,就不一定能获取到了。

这里留个思考题给大家:为什么说在线程池中不一定能获取到,而不是一定获取不到?要理解这个问题需要对线程池的工作原理、源码,以及InheritableThreadLocal源码理解,因此本篇不展开分析。

所以我们解决Bug就是将ThreadLocal换成InheritableThreadLocal,并且通过方法拦截器(HandlerInterceptor)或者过滤器(Filter)实现set session和remove session操作,推荐后者。

另外,从webmcv框架源码可以看出,RequestContextHolder#getRequestAttributes也是支持InheritableThreadLocal的,只是默认情况下不支持,需要修改配置。

getRequestAttributes方法会尝试从InheritableThreadLocal获取,源码如下。

(编辑:泉州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读