Spring+Shiro权限管理 (三) 使用Redis为Shiro权限验证加缓存

哈哈,好久没更,补上。

前一篇说到,Shiro默认情况下,权限验证会重复从数据库中查询,效率太低,且对增加了服务器的压力,所以面对这个问题,我使用了Redis来做缓存,减少重复从数据库查数据。

思路:

1、新增一个类,实现Shiro的 CacheManager 接口。

2、CacheManager接口需要一个Shiro的 Cache,所以我们创建一个类实现它,并重写方法。

3、applicationContext.xml中,把自定义的CacheManager配置进 SecurityManager里。

 

实现步骤:

1、导入jedis依赖

        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.8.0</version>
        </dependency>

2、创建RedisCacheManage (自定义Cache管理器)

public class RedisCacheManage implements CacheManager {

    @Resource
    private RedisCache redisCache;

    @Override
    public <K, V> Cache<K, V> getCache(String s) throws CacheException {
        return redisCache;
    }
}

3、创建RedisCache (RedisCacheManage需要的,使用Jedis重写增删改查)

@Component
public class RedisCache<K,V> implements Cache<K, V> {

    @Autowired
    private JedisUtil jedisUtil;

    @Override
    public V get(K k) throws CacheException {
        System.out.println("从Redis中获取权限数据");
        byte[] value = jedisUtil.get(getKey(k));
        if (value != null) {
            return (V) SerializationUtils.deserialize(value);
        }
        return null;
    }

    @Override
    public V put(K k, V v) throws CacheException {
        byte[] key = getKey(k);
        byte[] value = SerializationUtils.serialize(v);
        jedisUtil.set(key, value);
        jedisUtil.expire(key, 600);
        return v;
    }

    @Override
    public V remove(K k) throws CacheException {
        byte[] key = getKey(k);
        byte[] value = SerializationUtils.serialize(key);
        jedisUtil.del(key);
        if (value != null) {
            return (V) SerializationUtils.deserialize(value);
        }
        return null;
    }

    @Override
    public void clear() throws CacheException {

    }

    @Override
    public int size() {
        return 0;
    }

    @Override
    public Set<K> keys() {
        return null;
    }

    @Override
    public Collection<V> values() {
        return null;
    }

    private byte[] getKey(K k) {
        if (k instanceof String) {
            String CACHE_PREFIX = "shiro-cache";
            return (CACHE_PREFIX + k).getBytes();
        }
        return SerializationUtils.serialize(k);
    }
}

4、将RedisCacheManage配置进ApplicationContext.xml

 <!--SecurityManager即安全管理器,对全部的subject进行安全管理,它是shiro的核心,负责对所有的subject进行安全管理。-->
    <bean name="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realms">
            <list>
                <ref bean="userRealm"/>
            </list>
        </property>

        <!--shiro session共享管理-->
        <property name="sessionManager" ref="sessionManager"/>
        <!--shiro 权限缓存管理-->
        <property name="cacheManager" ref="redisCacheManager"/>
    </bean>


    <!--redis 管理 shiro cache-->
    <bean id="redisCacheManager" class="com.xcj.jquery_ajax.cache.RedisCacheManage"></bean>

5、JedisUtil (对Redis的操作工具类)

package com.xcj.jquery_ajax.tool;

import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

@Component
public class JedisUtil {

    @Autowired
    private JedisPool jedisPool;

    private Jedis getResource() {
        return jedisPool.getResource();
    }

    public byte[] set(byte[] key, byte[] value) {
        Jedis jedis = getResource();
        try {
            jedis.set(key, value);
            return value;
        } finally {
            jedis.close();
        }
    }

    public void expire(byte[] key, int i) {
        Jedis jedis = getResource();
        try {
            jedis.expire(key, i);
        } finally {
            jedis.close();
        }
    }

    public byte[] get(byte[] key) {
        Jedis jedis = getResource();
        try {
            byte[] bytes = jedis.get(key);
            return bytes;
        } finally {
            jedis.close();
        }
    }

    public void del(byte[] key) {
        Jedis jedis = getResource();
        try {
            jedis.del(key);
        } finally {
            jedis.close();
        }
    }

    public Set<byte[]> keys(String sHIRO_SESSION_PREFIX) {
        Jedis jedis = getResource();
        try {
            return jedis.keys((sHIRO_SESSION_PREFIX + "*").getBytes());
        } finally {
            jedis.close();
        }
    }
}

 

以上,就是Redis协助Shiro做权限缓存的内容。如果你对性能要求比较高,还可以在Redis的基础上,加个二级缓存(存在本地),由于本人还没研究过,就不多逼逼了,有兴趣的可以自行了解!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值