专栏首页卯金刀GGshiro的Cache机制

shiro的Cache机制

Shiro开发团队明白在许多应用程序中性能是至关重要的。Caching 是Shiro 中的一个重要功能,以确保安全操作保持尽可能的快。

但是,Shiro并不实现缓存的功能,Shiro 的缓存支持基本上是一个抽象的(包装)API,它将“坐”在一个基本的缓存机制产品(例 如,Ehcache,OSCache,Terracotta,Coherence,GigaSpaces,JBossCache 等)之上。这允许Shiro终端用户配置他们喜欢的任何缓存机制。

Caching API

Shiro 有三个重要的缓存接口:

1:CacheManager - 负责所有缓存的主要管理组件,它返回Cache 实例

2:Cache - 维护key/value 对

3:CacheManagerAware - 通过想要接收和使用CacheManager 实例的组件来实现

CacheManager 返回Cache 实例,各种不同的Shiro 组件使用这些Cache 实例来缓存必要的数据。任何实现了CacheManagerAware 的Shiro 组件将会自动地接收一个配置好的CacheManager,该CacheManager 能够用来获取Cache 实例。

Shiro 的SecurityManager 实现及所有AuthorizingRealm实现都实现了CacheManagerAware

Shiro 提供了一个个立即可用的EhCacheManager 实现

Caching 配置

通过在SecurityManager上设置了CacheManger,它反过来也会将它设置到实现了CacheManagerAware 的各种不同的Realm 上,示例如下:

spring-shiro.xml配置

<!-- 用户授权信息Cache, 采用EhCache --> <bean id="shiroEhcacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"> <property name="cacheManagerConfigFile" value="classpath:spring/ehcache-shiro.xml" /> </bean>

ehcache-shiro.xml

<ehcache updateCheck="false" name="shiroCache">

<diskStore path="java.io.tmpdir" /> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="false" diskPersistent="true" diskExpiryThreadIntervalSeconds="120" />

<cache name="shiro-activeSessionCache" maxElementsInMemory="10000" eternal="true" timeToLiveSeconds="0" timeToIdleSeconds="0" diskPersistent="true" overflowToDisk="false" diskExpiryThreadIntervalSeconds="600"> </cache> </ehcache>

name:缓存名称。 maxElementsInMemory:缓存最大个数。 eternal:对象是否永久有效,一但设置了,timeout将不起作用。 timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。 timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。 overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。 diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。 maxElementsOnDisk:硬盘最大缓存个数。 diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false. diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。 memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。 clearOnFlush:内存数量最大时是否清除。

包装使用其他的Cache框架

可以通过写一个类来实现Shiro的CacheManager,在这个类里面包装使用任何你想要使用的Cache框架,这里以使用Srping的缓存框架为例,参考如下:

public class MyCacheManager implements CacheManager {

public <K, V> Cache<K, V> getCache(String name) throws CacheException {

org.springframework.cache.Cache springCache = cacheManager.getCache(name);

return new SpringCacheWrapper(springCache);

}

class SpringCacheWrapper implements Cache {

private org.springframework.cache.Cache springCache;

SpringCacheWrapper(org.springframework.cache.Cache springCache) {

this.springCache = springCache;

}

public Object get(Object key) throws CacheException {

Object value = springCache.get(key);

if (value instanceof SimpleValueWrapper) {

return ((SimpleValueWrapper) value).get();

}

return value;

}

}

}

缓存数据同步更新的解决方案

使用Shiro的时候,缓存数据最大的问题就在于数据同步更新。

因为Shiro只负责验证部分,如果应用程序修改了人员的权限,那么就需要同步更新到Shiro里面去,也就是要同步Shiro的缓存数据。

一个解决方案就是完全废弃Shiro的缓存机制,自己在应用中控制数据的缓存

这里给出另一种简易可行的方案:

1:如果你使用的Spring,而且是自定义的Realm,那么可以在你的Realm里面添加一个方法来删除该用户的缓存数据,这样下次shiro在验证这个用户的时候,就会重新去获取数据,从而实现数据的同步

2:由于是自定义的Realm,可以把该对象作为Spring的bean,注入到你的业务对象中,在需要的时候就可以调用该方法来删除shiro的缓存数据了

示例,比如在前面自定义的MyRealm中,添加如下方法,示例如下:

public void removeUserCache(String userId){

SimplePrincipalCollection pc = new SimplePrincipalCollection();

pc.add(userId, super.getName());

super.clearCachedAuthorizationInfo(pc);

}

然后在HelloAnno中进行测试,示例如下:

1:要注入MyRealm,但注意需要使用getter/setter来注入

2:在main方法中,示例如下:

public static void main(String[] args) {

ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

HelloAnno t = (HelloAnno)ctx.getBean("helloAnno");

t.login();

t.t();

t.t();

t.getMr().removeUserCache("javass");

t.t();

}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • linux配置java环境变量

    一. 解压安装jdk 在shell终端下进入jdk-7u79-linux-x64.bin文件所在目录, 执行命令 ./jdk-7u79-linux-x64....

    用户5640963
  • 高并发Java(2):多线程基础

    使用线程的原因是,进程的切换是非常重量级的操作,非常消耗资源。如果使用多进程,那么并发数相对来说不会很高。而线程是更细小的调度单元,更加轻量级,所以线程会较为广...

    用户5640963
  • 【LeetCode-解题一 求和】

    Given an array of integers, return indices of the two numbers such that they add...

    用户5640963
  • 第十章:Shiro的Cache——深入浅出学Shiro细粒度权限开发框架

    概述 Shiro开发团队明白在许多应用程序中性能是至关重要的。Caching 是Shiro 中的一个重要功能,以确保安全操作保持尽可能的快。 但是,Shiro并...

    MonroeCode
  • 第十章:Shiro的Cache——深入浅出学Shiro细粒度权限开发框架

    Shiro开发团队明白在许多应用程序中性能是至关重要的。Caching 是Shiro 中的一个重要功能,以确保安全操作保持尽可能的快。

    MonroeCode
  • webservice 缓存机制

    本文转载:http://blog.csdn.net/zhdd1234/article/details/4555472

    跟着阿笨一起玩NET
  • 高阶干货|如何用gperftools分析深度学习框架的内存泄漏问题

    本系列为高阶干货,面向深度学习从业者,栏目会定期分享PaddlePaddle研发工程师和产品经理的行业经验。本篇和内存泄漏分析相关,适合中高阶深度学习工程师仔细...

    用户1386409
  • Spring还可以这样用缓存,你知道吗?

    大家在项目开发过程中,或多或少都用过缓存,为了减少数据库的压力,把数据放在缓存当中,当访问的请求过来时,直接从缓存读取。缓存一般都是基于内存的,读取速度比较快,...

    小忽悠
  • dell和ibm服务器串口重定向功能的配置

    重要:串口设置的时候,终端仿真模式和波特率必须设置一致,在这里统一设定终端仿真模式为vt100,波特率设置为115200。

    力哥聊运维与云计算
  • Kafka如何保证百万级写入速度已经保证不丢失不重复消费

    “这篇文章来聊一下Kafka的一些架构设计原理,这也是互联网公司面试时非常高频的技术考点。

    小勇DW3

扫码关注云+社区

领取腾讯云代金券