shiro实现session共享

旧街凉风 提交于 2020-03-01 14:29:17

session共享:在多应用系统中,如果使用了负载均衡,用户的请求会被分发到不同的应用中,A应用中的session数据在B应用中是获取不到的,就会带来共享的问题。

假设:用户第一次访问,连接的A服务器,进行了登录操作进入了系统,当用户再次操作时,请求被转发到了B服务器,用户并没有在B进行登录,此时用户又来到了登录页面,这是难以理解和接受的,这就引出了session共享。

对于shiro框架如何实现session的共享呢?shiro的共享分为两个方面,一个是session的共享,一个是cache的共享。接下来结合redis分别来实现这两个方面。

 

一.Session的共享

    

    shiro提供了自己的会话管理器sessionManager,其中有个属性叫sessionDao它来处理所有的会话信息。

    对于sessionDao,shiro也提供了自己的实现,常用的是ehcache的实现。Ehcache是jvm级别的,多个应用就会产生多个缓存示例,无法做到信息跨进程共享。要实现共享,就要重写sessionDao,通过实现我们自己的Dao,做到同一个会话信息的唯一性。

看下面一幅类图:

1.继承shiro提供的抽象sessionDao,重写create,read,delete等方法。

2.考虑系统的扩展性,我们抽象出一个数据仓储接口,并提供一个redis的实现方式。假如以后我们底层要换成数据库存储session数据,那只需扩展一个数据库的实现类并注入。

 

二.Cache的共享

 

同样的,shiro也提供了自己的缓存管理器:cacheManager,重写这个实现,来满足缓存的共享。

看下面的类图:

  1. 我们只需实现shiro的CacheManager和Cache接口即可。前者暴漏了获取Cache实例的方法,后者提供了Cache实例的增删改查操作。

  2. 中间一层的抽象是为了设计的良好,提供扩展性,后期有需要,只需增加ShiroCacheManager的实现类。

  3. JedisShiroCacheManager中的Cache实例通过ConCurrentHashMap进行缓存,防止对象的反复创建。

 

三.配置

 

3.1 Cache配置

<!-- redisManager-->

<bean id ="redisManager" class = "com.yingxinhuitong.shiro.util.RedisManager">
  <property name = "host"value = "127.0.0.1"/>
  <property name = "port"value = "6379"/>
  <property name = "expire"value = "1800"/>
  <!--<property name ="password" value=""/>-->
  <!--<property name ="timeout" value="0"/>-->
</bean>
<!-- shiro缓存 -->
<bean id = "shrioCacheManager" class ="com.yingxinhuitong.shiro.cache.JedisShiroCacheManager">

    <property name ="redisManager" ref = "redisManager"/>
</bean>
<bean id = "shiroJedisManager" class ="com.yingxinhuitong.shiro.cache.CustomShiroCacheManager">

    <property name ="shrioCacheManager" ref = "shrioCacheManager"/>
</bean>

 

3.2 sessionDao配置

<!-- 会话DAO -->

<bean id = "shiroSessionRepository"

  class = "com.yingxinhuitong.shiro.session.JedisShiroSessionRepository">

    <property name = "redisManager" ref = "redisManager"/></bean>

    <bean id = "sessionDAO" class = "com.yingxinhuitong.shiro.session.CustomShiroSessionDao"><property name = "sessionIdGenerator" ref = "sessionIdGenerator"/>

    <property name = "shiroSessionRepository" ref = "shiroSessionRepository"/>

</bean>

 

四.代码

参见:https://github.com/zljk0306/shiro-redis-share

 

关注老姜谈技术,微信号:helojava,或者扫描下面二维码。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!