目录

什么是shiro的会话管理

Shiro中的会话管理

Shiro基础组件

SessionManager

SessionListener

SessionDao

会话验证

会话案例

测试

缓存

什么是缓存

Ehcache(缓存)

ehcache的特点

ehcache、cacheManager和cache三者之间的关系

ehcache的使用


什么是shiro的会话管理

SessionManager(会话管理器):管理所有Subject的session包括创建、维护、删除、失效、验证等工作。

Shiro中的会话管理

在shiro里所有的用户的会话信息都会由Shiro来进行控制,shiro提供的会话可以用于JavaSE/JavaEE环境,不依赖于任何底层容器,可以独立使用,是完整的会话模块。通过Shiro的会话管理器(SessionManager)进行统一的会话管理

Shiro基础组件

SessionManager

  会话管理器管理着应用中所有 Subject 的会话的创建、维护、删除、失效、验证等工作。是Shiro 的核心组件,顶层组件SecurityManager直接继承了SessionManager,且提供了SessionsSecurityManager实现直接把会话管理委托给相应的SessionManager
          1)DefaultSessionManager:使用的默认实现,用于JavaSE环境
          2)ServletContainerSessionManager:使用的默认实现,用于Web环境,其直接使用Servlet容器的会话
          3)DefaultWebSessionManager:用于Web环境的实现,可以替代ServletContainerSessionManager,自己维护着会话,直接废弃了Servlet容器的会话管理

SessionListener

  SessionListener会话监听器用于监听会话创建、过期及停止事件。
  实现方式:
          1)实现SessionListener,必须实现所有方法
          2)继承SessionListenerAdapter,重写指定方法
  
  相关API:
          1)onStart(Session session):监听会话创建事件
          2)onStop(Session session):监听会话销毁事件
          3)onExpiration(Session session):监听会话过期事件

SessionDao

Shiro提供SessionDAO用于会话的CRUD,即DAO(Data Access Object)模式实现。

  •          AbstractSessionDAO:提供了SessionDAO的基础实现,如生成会话ID等
  •           CachingSessionDAO:提供了对开发者透明的会话缓存的功能,需要设置相应的CacheManager 
  •           MemorySessionDAO:直接在内存中进行会话维护(默认方式)
  •           EnterpriseCacheSessionDAO:提供了缓存功能的会话维护,默认情况下使用MapCache实现,内部使用ConcurrentHashMap保存缓存的会话。

相关API:

如DefaultSessionManager在创建完session后会调用该方法;

如保存到关系数据库/文件系统/NoSQL数据库;
    即可以实现会话的持久化;返回会话ID;主要此处返回的ID.equals(session.getId());  
  Serializable create(Session session);
  根据会话ID获取会话  
  Session readSession(Serializable sessionId) throws UnknownSessionException;  
  更新会话;如更新会话最后访问时间/停止会话/设置超时时间/设置移除属性等会调用  
  void update(Session session) throws UnknownSessionException;  
  删除会话;当会话过期/会话停止(如用户退出时)会调用  
  void delete(Session session);  
  获取当前所有活跃用户,如果用户量多此方法影响性能  
  Collection<Session> getActiveSessions();

会话验证

  •  Shiro提供了会话验证调度器,用于定期的验证会话是否已过期,如果过期将停止会话。
  • 出于性能考虑,一般情况下都是获取会话的同时来验证会话是否过期并停止会话的;但是如果在Web环境中,如果用户不主动退出是不知道会话是否过期的,因此需要定义的检测会话是否过期,Shiro提供了会话验证调度器来定期检查会话是否过期,SessionValidationScheduler 。
  • Shrio也提供了使用Quartz会话验证调度器 QuartzSessionValidationScheduler 。

会话案例

创建Session ID生成器

 <!-- Session ID 生成器 -->
  <bean id="sessionIdGenerator" class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator">
  </bean>

自定义会话管理

<!--sessionDao自定义会话管理,针对Session会话进行CRUD操作-->
  <bean id="customSessionDao" class="org.apache.shiro.session.mgt.eis.MemorySessionDAO">
      <property name="sessionIdGenerator" ref="sessionIdGenerator"/>
  </bean>

创建会话监听器

<!--会话监听器-->
  <bean id="shiroSessionListener" class="com.zking.ssm.book.shiro.ShiroSessionListener"/>

SessionListener的实现方式:

  • 实现SessionListener,必须实现所有方法
  • 继承SessionListenerAdapter,重写指定方法
package com.zking.ssm.book.shiro;


import org.apache.shiro.session.Session;
import org.apache.shiro.session.SessionListener;

/**
 * shiro的Session监听器实现方式
    1)实现SessionListener,必须实现所有方法
    2)继承SessionListenerAdapter,重写指定方法
 */
public class ShiroSessionListener implements SessionListener {

    @Override
    public void onStart(Session session) {
        System.out.println("【shiro的Session监听器】---onStart....uuid="+session.getId().toString());
    }

    @Override
    public void onStop(Session session) {
        System.out.println("【shiro的Session监听器】---onStop....uuid="+session.getId().toString());
    }

    @Override
    public void onExpiration(Session session) {
        System.out.println("【shiro的Session监听器】---onExpiration....uuid="+session.getId().toString());
    }
}

会话cookie模板

<!--会话cookie模板-->
  <bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
      <!--设置cookie的name-->
      <constructor-arg value="shiro.session"/>
      <!--设置cookie有效时间-->
      <property name="maxAge" value="-1"/>
      <!--设置httpOnly-->
      <property name="httpOnly" value="true"/>
  </bean>

SessionManager会话管理器

<!--SessionManager会话管理器-->
  <bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
      <!--设置session会话过期时间 毫秒 3分钟=180000-->
      <property name="globalSessionTimeout" value="180000"/>
      <!--设置sessionDao-->
      <property name="sessionDAO" ref="customSessionDao"/>
      <!--设置间隔多久检查一次session的有效性 默认60分钟-->
      <property name="sessionValidationInterval" value="1800000"/>
      <!--配置会话验证调度器-->
      <!--<property name="sessionValidationScheduler" ref="sessionValidationScheduler"/>-->
      <!--是否开启检测,默认开启-->
      <!--<property name="sessionValidationSchedulerEnabled" value="true"/>-->
      <!--是否删除无效的session,默认开启-->
      <property name="deleteInvalidSessions" value="true"/>
      <!--配置session监听器-->
      <property name="sessionListeners">
          <list>
              <ref bean="shiroSessionListener"/>
          </list>
      </property>
      <!--会话Cookie模板-->
      <property name="sessionIdCookie" ref="sessionIdCookie"/>
      <!--取消URL后面的JSESSIONID-->
      <property name="sessionIdUrlRewritingEnabled" value="false"/>
  </bean>

把会话管理配置好后,再配置到shiro的安全管理器中

测试

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6ZGrNzA5,size_20,color_FFFFFF,t_70,g_se,x_16

 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6ZGrNzA5,size_20,color_FFFFFF,t_70,g_se,x_16

 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6ZGrNzA5,size_20,color_FFFFFF,t_70,g_se,x_16

缓存

什么是缓存

  • 缓存的英文是cache,一般是用于RAM存储器,用于存储临时数据,断电后存储的内容会消失
  • 缓存对象,缓存管理器内可以放置若干cache,存放数据的实质,所有cache都实现了Ehcache接口
  • RAM是随机存储器,所有容易丢失

Ehcache(缓存)

  •  Ehcache是现在最流行的纯Java开源缓存框架,配置简单、结构清晰、功能强大。是Hibernate中默认CacheProvider。
  • Ehcache是一种广泛使用的开源Java分布式缓存。主要面向通用缓存,Java EE和轻量级容器。
  • 它具有内存和磁盘存储,缓存加载器,缓存扩展,缓存异常处理程序,一个gzip缓存servlet过滤器,支持REST和SOAP api等特点。
  • Ehcache的核心是cacheManager,一切的Ehcache的应用都是从cacheManager开始的。

ehcache的特点

  • 够快

      Ehcache的发行有一段时长了,经过几年的努力和不计其数的性能测试,Ehcache终被设计于large, high concurrency systems.

  • 够简单

      开发者提供的接口非常简单明了,从Ehcache的搭建到运用运行仅仅需要的是你宝贵的几分钟。其实很多开发者都不知道自己用在用Ehcache,Ehcache被广泛的运用于其他的开源项目

  • 够袖珍

      关于这点的特性,官方给了一个很可爱的名字small foot print ,一般Ehcache的发布版本不会到2M,V 2.2.3 才 668KB。

  • 够轻量

      核心程序仅仅依赖slf4j这一个包,没有之一!

  •  好扩展

      Ehcache提供了对大数据的内存和硬盘的存储,最近版本允许多实例、保存对象高灵活性、提供LRU、LFU、FIFO淘汰算法,基础属性支持热配置、支持的插件多

  • 监听器

      缓存管理器监听器 (CacheManagerListener)和 缓存监听器(CacheEvenListener),做一些统计或数据一致性广播挺好用的

  • 分布式缓存

      从Ehcache 1.2开始,支持高性能的分布式缓存,兼具灵活性和扩展性

ehcache、cacheManager和cache三者之间的关系

cacheManager:缓存管理框架(cacheManager)是ehcache的核心,它的主要职责是对cache的创建、移除和访问。

  • ehcache的核心是cacheManager,cacheManager是用来管理cache(缓存)的。
  • 一个应用下可以有多个cacheManager,而一个cacheManager下又可以有多个cache
  • cache内部保存的是一个的element,一个element中保存的是一个key和value的配对。

ehcache的使用

导入相关的依赖

<!-- 添加ehcache -->
<dependency>
     <groupId>net.sf.ehcache</groupId>
     <artifactId>ehcache</artifactId>
     <version>1.4.1</version>
  </dependency>

<!-- 添加shiro spring-->
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-spring</artifactId>
      <version>${shiro.version}</version>
    </dependency>

    <!-- 添加shiro ehcache -->
    <dependency>
      <groupId>org.apache.shiro</groupId>
      <artifactId>shiro-ehcache</artifactId>
      <version>${shiro.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>${spring.version}</version>
    </dependency>

创建集成配置文件spring-ehcache.xml与spring集成

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--使用ehcache缓存-->
    <bean id="cacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
        <property name="configLocation" value="classpath:ehcache.xml"/>
        <property name="shared" value="true"/>
    </bean>

    <!-- 默认是cacheManager  创建缓存管理器-->
    <bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
        <property name="cacheManager" ref="cacheManagerFactory"/>
    </bean>
</beans>

再在配置文件spring-shiro.xml中的配置

1、在自定义Realm中

<!--开启缓存-->
        <property name="cachingEnabled" value="true"/>
        <!--开启授权缓存-->
        <property name="authorizationCachingEnabled" value="true"/>
        <!--设置ehcache的中的缓存对象名-->
        <property name="authorizationCacheName" value="shiroAuthzCache"/>

2、在安全管理器中配置缓存管理器

<!--设置缓存管理器-->
        <property name="cacheManager" ref="cacheManager"/>

配置完成后,只需要在登录时访问数据库并查询该用户的权限,并存到缓存中,当需要查看此用户的权限时,不会再次去访问数据库,而是去缓存中查询。

至此,Shiro会话管理及缓存介绍完毕,由于作者水平有限难免有疏漏,欢迎留言纠错。