本文大纲

  • 一、简介
  • 二、缓存的概念
  • 三、自定义实现缓存机制
  • 四、什么是Ehcache
  • 五、Ehcache怎么用
  • 六、Spring对缓存的支持
  • 七、Spring+Ehcache实现
  • 八、Spring+Shiro+Ehcache实现
  • 九、总结

一、简介

在项目中,用到Shiro来做验证授权的控制。但在实际使用的时候,发现用户每访问一个功能,都会重新到UserRealm中获取一次权限。这样子会花费大量的系统系统。此时就想到了使用缓存,查了一下,Shiro也确实支持Authorization和Authentication做缓存,那就果断使用。

但说到缓存,究竟是怎么一回事呢?这里我将从零开始向大家介绍一下缓存。由于网上已经有很多具体实现的文章了,本文内容是对缓存知识的逐步进阶整理,目的是让大家能从零开始对缓存进行了解,直到懂得如何实现Spring+Shiro+Ehcache的缓存配置。文章中不会重复网上能找到的一大堆内容,并会给出相关的参考文章给大家参考。

二、缓存的概念

1、缓存简介

缓存,简单来说,就是让数据更接近于使用者。工作机制是:先从缓存中读取数据,如果没有再从慢速设备上(如数据库)读取实际数据(数据也会存入缓存)。

2、缓存策略

缓存中数据都有一定的生命周期,什么时候移除、什么时候到期,都有一定的讲究。主要分下面三点。

2.1 移除策略

移除策略,即如果缓存满了,从缓存中移除数据的策略;常见的有LFU、LRU、FIFO:

FIFO(First In First Out):先进先出算法,即先放入缓存的先被移除;

LRU(Least Recently Used):最久未使用算法,使用时间距离现在最久的那个被移除;

LFU(Least Frequently Used):最近最少使用算法,一定时间段内使用次数(频率)最少的那个被移除;

2.2 TTL(Time To Live )

存活期,即从缓存中创建时间点开始直到它到期的一个时间段(不管在这个时间段内有没有访问都将过期)

2.3 TTI(Time To Idle)

空闲期,即一个数据多久没被访问将从缓存中移除的时间。

3、参考资料

可参看此文的缓存简介:http://jinnianshilongnian.iteye.com/blog/2001040

三、自定义实现缓存机制

1 实现步骤

实现简单的缓存机制,通常只需实现下面四点:

  1. 确定用什么来做cache,通常使用ConcurrentHashMap键值对来做cache。
  2. 创建缓存管理器CacheManager,缓存管理器主要实现以下内容:
    1. 创建一个cache并进行管理
    2. 通过key来获取value的方法
    3. 根据key更新或新增缓存中的记录的方法
    4. 根据key来删除缓存中一条记录的方法
    5. 清空缓存中的所有记录的方法
  3. 在Service实现类中,当查询内容的时候,先查询缓存中的内容,若有,则返回;若无,则查询数据库中的内容,同时将查询结果加到缓存中。
  4. 在数据库数据有更新的时候,注意调用方法更新缓存中的数据。

只要选择好cache,和创建好CacheManager,就可以在Service中,通过创建CacheManager来管理缓存了。

2 存在问题

但我们自己做出来的缓存由于比较简单考虑得没那么全面,所以问题也不少,如:

  1. 与业务逻辑代码耦合度很高,需要在Service的方法中调用CacheManager的很多逻辑,不便于维护。
  2. 程序不够灵活,无法根据不同的条件进行缓存。
  3. 没有完善的移除策略,需要开发人员在业务逻辑中进行控制,难以维护。
  4. 不通用,无法使用第三方提供的缓存框架。

等等。

3 参考资料

由于网上已有很多实现的文章,这里不做重复。例如可参考:

http://blog.csdn.net/fanzhanwei/article/details/44958297

四、什么是Ehcache

上一节是自定义缓存的实现,可以看出,自己可以做一个简单的缓存,但是不够完善。其实已经有很多第三方的缓存框架,有完善的机制,可以给我们使用,而ehcache就是这样一种缓存框架。

1 Ehcache简介

EhCache是一个纯Java的进程内缓存框架,具有快速、精干等特点,也是Hibernate中默认的CacheProvider。它会把查出来的数据存储在内存或者磁盘中,以节省查询数据库的压力。

2 Ehcache使用条件

  • 比较少更新的表数据

    因为如果更新很频繁的数据,那就没有缓存的必要了,可能还会增加开销呢。

  • 对数据一致性要求不高的情况

    听说Ehcache的同步不是很完善,会造成不同服务器上的Ehcache缓存同步未必及时,这样可能会造成用户在获取数据的时候不一致。

3 Ehcache使用场景

  • 页面缓存
  • 对象缓存
  • 数据库数据缓存

五、Ehcache怎么用

1 Ehcache使用步骤

使用Ehcache,基本步骤如下:

  1. 创建一个ehcache.xml的配置文件,里面会有磁盘缓存位置、缓存配置等信息。
  2. 创建CacheManager,并读取相应的xml配置
    1. 直接CacheManager cacheManage = new CacheManager(),读取默认配置文件。
    2. 通过静态方法create()创建,加载默认配置。
    3. 通过newInstance()工厂方法创建,newInstance()会有几个重载,可以传入String、URL、InputStream等来加载配置文件。
  3. 创建Cache,可以在ehcache.xml等配置文件中配置好,也可以直接通过API创建cache,然后通过cacheManager.addCache()方法将cache加到缓存管理器中。
  4. 通过cacheManager.getCache()方法获取Cache
  5. 创建Element对象,存放键值对。
  6. 将创建的Element对象存放到cache中。
  7. 通过以上步骤,就已经把缓存弄好并存了相关内容到缓存中了。要想获得缓存中的内容,就逆向操作,先使用cache.get()把Element获取出来,接着通过Element.getObjectValue()获取到相应的值。

2 Ehcache配置文件

关于配置文件,默认情况下会加载classpath下名为ehcache.xml的配置文件。如果加载失败,会加载Ehcache报中的ehcache-failsafe.xml文件,这个文件中含有简单的默认配置。

在ehcache.xml配置文件中,需要了解各参数的意思,以下是一个范例:

  • name:缓存名称。
  • maxElementsInMemory:缓存最大个数。
  • eternal:缓存中对象是否为永久的,如果是,超时设置将被忽略,对象从不过期。
  • timeToIdleSeconds:置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
  • timeToLiveSeconds:缓存数据的生存时间(TTL),也就是一个元素从构建到消亡的最大时间间隔值,这只能在元素不是永久驻留时有效,如果该值是0就意味着元素可以停顿无穷长的时间。
  • maxEntriesLocalDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。
  • overflowToDisk:内存不足时,是否启用磁盘缓存。
  • diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
  • maxElementsOnDisk:硬盘最大缓存个数。
  • diskPersistent:是否在VM重启时存储硬盘的缓存数据。默认值是false。
  • diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
  • memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
  • clearOnFlush:内存数量最大时是否清除。

3 参考资料

具体例子可参考此网站:http://www.cnblogs.com/jingmoxukong/p/5975994.html

六、Spring对缓存的支持

1 Spring配置

Spring本身有对缓存方案的简单实现,可通过注释驱动来实现缓存机制。缓存中,最重要的两个概念就是CacheManager和Cache,Spring中的实现分别是:

  • CacheManager:org.springframework.cache.support.SimpleCacheManager
  • Cache:org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean

另外加上缓存的注解驱动配置:<cache:annotation-driven />

所以关键的spring xml配置文件如下:

2 重要注释

在Spring缓存中,关键是在方法中增加@Cacheable、@CachePut、@CacheEvict三个注释,然后方法内注意实现业务逻辑就好,无需像《第二部分:自定义实现缓存机制》那样子要参杂很多的缓存管理逻辑,这就是第三方缓存框架的一大好处。实际上Spring是通过Spring AOP,在方法的调用前后,分别拦截参数和返回值,来实现缓存的录入的。关于上面上个注释的作用如下:

  • @Cacheable:主要针对方法配置,能够根据方法的请求参数对其结果进行缓存。
  • @CachePut:主要针对方法配置,能够根据方法的请求参数对其结果进行缓存,和@Cacheable不同的是,它每次都会触发真实方法的调用。
  • @CacheEvict,主要针对方法配置,能够根据一定的条件对缓存进行清空。

具体例子可参考此网站:https://www.ibm.com/developerworks/cn/opensource/os-cn-spring-cache/

七、Spring+Ehcache实现

Spring cache能满足一些基本的缓存需求,但如果需求复杂了,用户量上去了,或者性能要求高了,Spring cache就估计难以支持了。因为它不支持高可用性,也不具备持久化数据的能力,这个时候就需要用到第三方的缓存方案,但还是用Spring的API,代码无需改动。这就是最理想的状态了,而Spring也支持这一点。

要配置实用Ehcache,主要改动Spring的xml配置文件,将cacheManager这个bean的具体实现由org.springframework.cache.support.SimpleCacheManager改为org.springframework.cache.ehcache.EhCacheCacheManager,并引用org.springframework.cache.ehcache.EhCacheManagerFactoryBean这个bean。此两个类的作用:

org.springframework.cache.ehcache.EhCacheManagerFactoryBean:加载Ehcache配置文件。

org.springframework.cache.ehcache.EhCacheCacheManager:支持net.sf.ehcache.CacheManager。

配置文件如下:

具体例子可参考此网站:http://www.cnblogs.com/jingmoxukong/p/5975994.html

八、Spring+Shiro+Ehcache实现

1 配置cacheManager

如果要集成Shiro,这里又得在Spring的xml配置文件中修改一下cacheManager的实现类,将其改为org.apache.shiro.cache.ehcache.EhCacheManager。如下:

<!-- 缓存管理器 使用Ehcache实现 -->
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
  <property name="cacheManagerConfigFile" value="classpath:ehcache.xml"/>
</bean>

这样就可以使用适合shiro的Ehcache的CacheManager了。

2 配置Realm

修改Realm的bean,指定其cache相关属性的值,如下:

<!-- Realm实现 -->
<bean id="userRealm" class="com.huangzijian.realm.UserRealm">
  <property name="cachingEnabled" value="true"/>
  <property name="authenticationCachingEnabled" value="true"/>
  <property name="authenticationCacheName" value="authenticationCache"/>
  <property name="authorizationCachingEnabled" value="true"/>
  <property name="authorizationCacheName" value="authorizationCache"/>
</bean>

注意此处的cacheName,就是指在Ehcache中配置的cache,也就是通常在ehcache.xml中定义的cacahe。

3 配置securityManager

需要在securityManager中配置cacheManager属性,引用配好的cacheManager,如下:

<!-- 安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.mgt.DefaultSecurityManager">
  <property name="realms">
    <list>
      <ref bean="userRealm"/>
    </list>
  </property>
  <property name="sessionManager" ref="sessionManager"/>
  <property name="cacheManager" ref="cacheManager"/>
</bean>

经过上面三步,即可激活Shiro的Authentication和Authorization的缓存机制,从而不必要每次都读取数据库来确定该人员的角色之类的,极大的节省了资源。

九、总结

通过上述一步一步的进阶,相信大家都可以实现自己想要的缓存了。本文是通过要实现shiro中的Authorization和Authentication缓存,来逐步让大家接触起缓存的使用。对于缓存的使用,还有很多更深入的内容,这里只做了抛砖引玉,有待大家以后的使用了解了。

从零到实现Shiro中Authorization和Authentication的缓存的更多相关文章

  1. Shiro learning - 入门学习 Shiro中的基础知识(1)

    Shiro入门学习 一 .什么是Shiro? 看一下官网对于 what is Shiro ? 的解释 Apache Shiro (pronounced “shee-roh”, the Japanese ...

  2. shiro中 UnknownAccountException

    一 shiro的session.request和response与服务端容器自身的这三个对象的关系 在web.xml中配置了一个Filter,拦截/*,所有的uri.在拦截器中还会调用ShiroFil ...

  3. shiro中CacheManager相关的类结构介绍,提供redis Cache实现

    cacheManager主要用于对shiro中的session.realm中的认证信息.授权信息进行缓存. 1.类结构 2.接口及类介绍 CacheManager 提供根据名字获取cache的作用. ...

  4. Shiro中的授权问题(二)

    上篇博客(Shiro中的授权问题 )我们介绍了Shiro中最最基本的授权问题,以及常见的权限字符的匹配问题.但是这里边还有许多细节需要我们继续介绍,本节我们就来看看Shiro中授权的一些细节问题. 验 ...

  5. Shiro中的授权问题

    在初识Shiro一文中,我们对Shiro的基本使用已经做了简单的介绍,不懂的小伙伴们可以先阅读上文,今天我们就来看看Shiro中的授权问题. Shiro中的授权,大体上可以分为两大类,一类是隐式角色, ...

  6. Shiro中的Rememberme后出现浏览器500错误

    问题详述:在Shiro中添加Remember me功能后,只要勾选Remember me选项为true的时候,浏览器就会跳转到一个不可达页面,并且在Chrome中显示HTTP 500错误. 问题追踪: ...

  7. shiro中自定义realm实现md5散列算法加密的模拟

    shiro中自定义realm实现md5散列算法加密的模拟.首先:我这里是做了一下shiro 自定义realm散列模拟,并没有真正链接数据库,因为那样东西就更多了,相信学到shiro的人对连接数据库的一 ...

  8. Shiro中Realm

    6.1 Realm [2.5 Realm]及[3.5 Authorizer]部分都已经详细介绍过Realm了,接下来再来看一下一般真实环境下的Realm如何实现. 1.定义实体及关系   即用户-角色 ...

  9. 学习Spring Boot:(十九)Shiro 中使用缓存

    前言 在 shiro 中每次去拦截请求进行权限认证的时候,都会去数据库查询该用户的所有权限信息, 这个时候就是有一个问题了,因为用户的权限信息在短时间内是不可变的,每次查询出来的数据其实都是重复数据, ...

随机推荐

  1. MySQL学习分享-->日期时间类型

    日期时间类型 ①如果要用来表示年月日时分秒,一般使用datetime类型: ②如果要用来表示年月日,一般使用date类型: ③如果要表示时分秒,一般使用time类型: ④如果只是表示年份,一般使用ye ...

  2. Spring总结_02_Spring概述

    一.概念准备 1.应用程序:是能完成我们所需要功能的成品,比如购物网站.OA系统. 2.框架:是能完成一定功能的半成品,比如我们可以使用框架进行购物网站开发:框架做一部分功能,我们自己做一部分功能,这 ...

  3. 1212: [HNOI2004]L语言

    1212: [HNOI2004]L语言 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 643  Solved: 252[Submit][Status] ...

  4. java配置文件的读写

    最近在做一个爬虫项目时,用到了读写配置文件的方法,记录下来以后可能用的到. Properties pro = new Properties(); boolean IsFirst = true; //从 ...

  5. Java 反射的理解

    反射反射,程序员的快乐,今天你快乐了吗?如果你不快乐,没关系,接下来让你快乐起来! 一.什么是反射? 通过百度百科我们可以知道,Java反射就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性 ...

  6. mysql命令[转]

    来自:http://www.cnblogs.com/zhangzhu/archive/2013/07/04/3172486.html 1.连接到本机上的MYSQL.首先打开DOS窗口,然后进入目录my ...

  7. H5 内联 SVG

    HTML5 内联 SVG HTML5 画布 HTML5 画布 vs SVG HTML5 支持内联 SVG. 什么是SVG? SVG 指可伸缩矢量图形 (Scalable Vector Graphics ...

  8. 一个想法照进现实-《IT连》创业项目:关于团队组建

    前言: 从上一篇<三天的风投对接活动内幕分享>归来后,从中领悟了不少内涵. 之后暂停了找钱的想法,这些天也拒绝了不少想要参与众筹的同学. 目前主要精力放在以下三件事: 1:重新规划顶层设计 ...

  9. DAX基础入门 - 30分钟从SQL到DAX -- PowerBI 利器

    看到漂漂亮亮的PowerBI报表,手痒痒怎么办?! 有没有面对着稀奇古怪的DAX而感到有点丈八金刚摸不着头脑或者干瞪眼?! 有没有想得到某个值想不出来DAX怎么写而直跳脚!? 看完这篇文章,你会恍然大 ...

  10. border-radius IE8兼容处理

    根据canisue(http://caniuse.com/#search=border-radius),border-radius兼容性如下图所示: 测试代码: <!DOCTYPE html&g ...