• shiro实现session共享(本文转自店蛋蛋)


    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,delte等方法。

    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

  • 相关阅读:
    java算法
    2012 要找回曾经的忘我的激情
    啊啊啊
    利用ORACLE JOB 模拟多线程应用
    有没有一种数据库叫思科
    且行好事,莫问前程
    女人浪漫的好点子
    What is the difference between interface and abstract class
    优秀是一种习惯
    C#判断ContextMenuStrip右键菜单的来源(从哪个控件弹出来的) (转载)
  • 原文地址:https://www.cnblogs.com/taiyanhong/p/7099748.html
Copyright © 2020-2023  润新知