Shiro-菜鸟实战篇-缓存管理

我只是一个虾纸丫 提交于 2019-12-22 00:43:55

先看下面的测试类及测试结果

    @Test
    public void bufferTest(){
        Subject subject=ShiroUtil.login("zhangsan","123456");
        subject.isPermitted("sys:user:list");
        subject.isPermitted("sys:user:list");
        subject.isPermitted("sys:user:list");
    
  }
}

在这里插入图片描述
我们会发现授权完成运行了3次,这并不是我们想看到的。

为什么要使用缓存?
在没有使用缓存的情况下,每发送一次请求都会调用一次doGetAuthorizationInfo方法来进行用户的授权操作,但是我们知道,一个用户具有的权限一般不会频繁的修改,也就是每次授权的内容都是一样的,所以我们希望在用户登录成功的第一次授权成功后将用户的权限保存在缓存中,下一次请求授权的话就直接从缓存中获取,这样效率会更高一些。

下面说几种缓存办法。

使用内置缓存
在shiro系列文章第一篇我们就已经提及到了CacheManager(缓存管理器),这是shiro封装好的内置缓存器,现在我们来使用一下它。

看下我们的自定义的工具类
在这里插入图片描述
其实只要创建一个缓存管理器,并放入我们的安全管理器中就可以了。
我们对工具类进行如下修改

public class ShiroUtil {
    static {
        //1.初始化shiro的安全管理器
        DefaultSecurityManager securityManager=new DefaultSecurityManager();
        //2.设置用户的权限信息到安全管理器
       // Realm realm=new IniRealm("classpath:shiro.ini");
        Realm realm=new ShiroRealm();
        securityManager.setRealm(realm);
        //------------------------创建缓存管理器-------------------------------
        CacheManager cacheManager=new MemoryConstrainedCacheManager();
        securityManager.setCacheManager(cacheManager);
         //--------------------------------------------------------
        //3.使用SecurityUtils将securityManager设置到运行环境中
        SecurityUtils.setSecurityManager(securityManager);
    }
    public static Subject login(String name,String password){
        //4.创建一个Subject实例,该实例认证要使用上面创建的securityManager进行
        Subject subject=SecurityUtils.getSubject();
        //5.创建token令牌,记录用户认证的身份和凭证即证号和密码

        UsernamePasswordToken token=new UsernamePasswordToken(name,password);
        //6.主体要进行登录,登录的时候进行认证的检查
        subject.login(token);
        System.out.println("用户认证状态:"+subject.isAuthenticated());
        return subject;
    }
}

下面我们再测试一下,可以如下结果
在这里插入图片描述

使用ehcache

导入坐标

<dependency>
    <groupId>org.apache.shiro</groupId>
    <artifactId>shiro-ehcache</artifactId>
    <version>1.3.2</version>
</dependency>

对工具类进行修改

public class ShiroUtil {
    static {
        //1.初始化shiro的安全管理器
        DefaultSecurityManager securityManager=new DefaultSecurityManager();
        //2.设置用户的权限信息到安全管理器
       // Realm realm=new IniRealm("classpath:shiro.ini");
        Realm realm=new ShiroRealm();
        securityManager.setRealm(realm);
        //使用内置缓存创建缓存管理器
       // CacheManager cacheManager=new MemoryConstrainedCacheManager();
        //使用第3方缓存创建缓存管理器
        CacheManager cacheManager=new EhCacheManager();
        securityManager.setCacheManager(cacheManager);
        //使用第3方缓存创建缓存管理器
        //3.使用SecurityUtils将securityManager设置到运行环境中
        SecurityUtils.setSecurityManager(securityManager);
    }
    public static Subject login(String name,String password){
        //4.创建一个Subject实例,该实例认证要使用上面创建的securityManager进行
        Subject subject=SecurityUtils.getSubject();
        //5.创建token令牌,记录用户认证的身份和凭证即证号和密码

        UsernamePasswordToken token=new UsernamePasswordToken(name,password);
        //6.主体要进行登录,登录的时候进行认证的检查
        subject.login(token);
        System.out.println("用户认证状态:"+subject.isAuthenticated());
        return subject;
    }
}

测试类进行测试
在这里插入图片描述上面并没有对ehcache的参数进行配置,所用的是默认参数,下面我们对ehcache参数进行一些配置

ehcache参数配置
看下默认配置
在这里插入图片描述

<ehcache>
    <diskStore path="java.io.tmpdir/shiro-ehcache"/>
    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="false"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
    />
    <cache name="shiro-activeSessionCache"
           maxElementsInMemory="10000"
           overflowToDisk="true"
           eternal="true"
           timeToLiveSeconds="0"
           timeToIdleSeconds="0"
           diskPersistent="true"
           diskExpiryThreadIntervalSeconds="600"/>
    <cache name="org.apache.shiro.realm.text.PropertiesRealm-0-accounts"
           maxElementsInMemory="1000"
           eternal="true"
           overflowToDisk="true"/>
</ehcache>

常用参数说明:

eternal
缓存中对象是否为永久的,如果是,超时设置将被忽略,对象永不为奴(emm……永不过期)
maxElementsInMemory
缓存中允许创建的最大对象数
overflowToDisk
内存不足时,是否启用磁盘缓存
timeToIdleSeconds
缓存数据的钝化时间,也就是在一个元素消亡之前,两次访问时间的最大时间间隔值。
这只能在元素不是永久驻留时有效,如果该值是0就意味着元素可以停顿无穷长的时间。
timeToLiveSeconds
缓存数据的生存时间,也就是一个元素从构建到消亡的最大时间间隔值,这只能在元素不是永久驻留时有效,如果该值是0就意味着元素可以停顿无穷长的时间。
diskPersistent
设定在虚拟机重启时是否进行磁盘存储,默认为false
memoryStoreEvictionPolicy
缓存满了之后的淘汰算法。
1.FIFO,先进先出
2.LFU,最少被使用,缓存的元素有一个hit属性,hit值最小的将会被清出缓存
3.LRU,最近最少使用的,缓存的元素有一个时间戳,当缓存容器满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。

上文链接:https://haosy.blog.csdn.net/article/details/103645878
Shiro系列专题链接:https://blog.csdn.net/qq_43518645/category_9604248.html
2019/12/21学习记录。

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