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

哈哈,好久没更,补上。

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

思路:

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

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

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

 

实现步骤:

1、导入jedis依赖

        
            redis.clients
            jedis
            2.8.0
        

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

public class RedisCacheManage implements CacheManager {

    @Resource
    private RedisCache redisCache;

    @Override
    public  Cache getCache(String s) throws CacheException {
        return redisCache;
    }
}

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

@Component
public class RedisCache implements Cache {

    @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 keys() {
        return null;
    }

    @Override
    public Collection 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

 
    
        
            
                
            
        

        
        
        
        
    


    
    

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 keys(String sHIRO_SESSION_PREFIX) {
        Jedis jedis = getResource();
        try {
            return jedis.keys((sHIRO_SESSION_PREFIX + "*").getBytes());
        } finally {
            jedis.close();
        }
    }
}

 

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

你可能感兴趣的:(Shiro)