shiro缓存
1.cache接口
cache接口主要定义了针对缓存的一些操作,下边是shiro中cache接口的一些相关方法
public interface Cache<K, V> {
// 得到缓存
V get(K var1) throws CacheException;
// 放入缓存
V put(K var1, V var2) throws CacheException;
// 去除缓存
V remove(K var1) throws CacheException;
// 清空所有元素
void clear() throws CacheException;
// 大小
int size();
// keys集合
Set<K> keys();
// values集合
Collection<V> values();
}
cache接口有两个实现类
1.MapCache
从源码可以看到,MapCache主要是通过一个map来实现缓存
public class MapCache<K, V> implements Cache<K, V> {
private final Map<K, V> map;
private final String name;
public MapCache(String name, Map<K, V> backingMap) {
if (name == null) {
throw new IllegalArgumentException("Cache name cannot be null.");
} else if (backingMap == null) {
throw new IllegalArgumentException("Backing map cannot be null.");
} else {
this.name = name;
this.map = backingMap;
}
}
public V get(K key) throws CacheException {
return this.map.get(key);
}
public V put(K key, V value) throws CacheException {
return this.map.put(key, value);
}
public V remove(K key) throws CacheException {
return this.map.remove(key);
}
public void clear() throws CacheException {
this.map.clear();
}
public int size() {
return this.map.size();
}
public Set<K> keys() {
Set<K> keys = this.map.keySet();
return !keys.isEmpty() ? Collections.unmodifiableSet(keys) : Collections.emptySet();
}
public Collection<V> values() {
Collection<V> values = this.map.values();
return (Collection)(!this.map.isEmpty() ? Collections.unmodifiableCollection(values) : Collections.emptySet());
}
public String toString() {
return "MapCache '" + this.name + "' (" + this.map.size() + " entries)";
}
}
2.RedisCache
而redisCache呢则是通过redis缓存中间件,通过jedis实现缓存机制,需要注入redis缓存管理器
public class RedisCache<K, V> implements Cache<K, V> {
private Logger logger;
private RedisManager cache;
private String keyPrefix;
public String getKeyPrefix() {
return this.keyPrefix;
}
public void setKeyPrefix(String keyPrefix) {
this.keyPrefix = keyPrefix;
}
public RedisCache(RedisManager cache) {
this.logger = LoggerFactory.getLogger(this.getClass());
this.keyPrefix = "shiro_redis_session:";
if (cache == null) {
throw new IllegalArgumentException("Cache argument cannot be null.");
} else {
this.cache = cache;
}
}
public RedisCache(RedisManager cache, String prefix) {
this(cache);
this.keyPrefix = prefix;
}
private byte[] getByteKey(K key) {
if (key instanceof String) {
String preKey = this.keyPrefix + key;
return preKey.getBytes();
} else {
return SerializeUtils.serialize(key);
}
}
public V get(K key) throws CacheException {
this.logger.debug("根据key从Redis中获取对象 key [" + key + "]");
try {
if (key == null) {
return null;
} else {
byte[] rawValue = this.cache.get(this.getByteKey(key));
V value = SerializeUtils.deserialize(rawValue);
return value;
}
} catch (Throwable var4) {
throw new CacheException(var4);
}
}
public V put(K key, V value) throws CacheException {
this.logger.debug("根据key从存储 key [" + key + "]");
try {
this.cache.set(this.getByteKey(key), SerializeUtils.serialize(value));
return value;
} catch (Throwable var4) {
throw new CacheException(var4);
}
}
public V remove(K key) throws CacheException {
this.logger.debug("从redis中删除 key [" + key + "]");
try {
V previous = this.get(key);
this.cache.del(this.getByteKey(key));
return previous;
} catch (Throwable var3) {
throw new CacheException(var3);
}
}
public void clear() throws CacheException {
this.logger.debug("从redis中删除所有元素");
try {
this.cache.flushDB();
} catch (Throwable var2) {
throw new CacheException(var2);
}
}
public int size() {
try {
Long longSize = new Long(this.cache.dbSize());
return longSize.intValue();
} catch (Throwable var2) {
throw new CacheException(var2);
}
}
public Set<K> keys() {
try {
Set<byte[]> keys = this.cache.keys(this.keyPrefix + "*");
if (CollectionUtils.isEmpty(keys)) {
return Collections.emptySet();
} else {
Set<K> newKeys = new HashSet();
Iterator i$ = keys.iterator();
while(i$.hasNext()) {
byte[] key = (byte[])i$.next();
newKeys.add(key);
}
return newKeys;
}
} catch (Throwable var5) {
throw new CacheException(var5);
}
}
public Collection<V> values() {
try {
Set<byte[]> keys = this.cache.keys(this.keyPrefix + "*");
if (!CollectionUtils.isEmpty(keys)) {
List<V> values = new ArrayList(keys.size());
Iterator i$ = keys.iterator();
while(i$.hasNext()) {
byte[] key = (byte[])i$.next();
V value = this.get(key);
if (value != null) {
values.add(value);
}
}
return Collections.unmodifiableList(values);
} else {
return Collections.emptyList();
}
} catch (Throwable var6) {
throw new CacheException(var6);
}
}
}
从上面的需要注入缓存管理器开始,也看一看shiro中的缓存管理器,CacheManager - 负责所有缓存的主要管理组件,它返回 Cache 实例。
shiro中缓存管理器也有一个顶层接口
CacheManager 返回cache实例
public interface CacheManager {
<K, V> Cache<K, V> getCache(String var1) throws CacheException;
}
他有几个实现类,就不一一详细解释,我就看看我比较常用的redis的缓存管理器吧,redisManager定义了一个ConcurrentHashMap,我不知道这样解释好不好,试一下吧,个人理解就是,每一个缓存是一个Map<key,value> 这样的map,而缓存管理器则管理着很多很多这样的map,因此ConcurrentHashMap<name.cache>,需要注入的redis管理器其实就是redis的一些基本的配置,像端口号,密码什么的。
public class RedisCacheManager implements CacheManager {
private static final Logger logger = LoggerFactory.getLogger(RedisCacheManager.class);
private final ConcurrentMap<String, Cache> caches = new ConcurrentHashMap();
private RedisManager redisManager;
private String keyPrefix = "shiro_redis_cache:";
public RedisCacheManager() {
}
public String getKeyPrefix() {
return this.keyPrefix;
}
public void setKeyPrefix(String keyPrefix) {
this.keyPrefix = keyPrefix;
}
public <K, V> Cache<K, V> getCache(String name) throws CacheException {
logger.debug("获取名称为: " + name + " 的RedisCache实例");
Cache c = (Cache)this.caches.get(name);
if (c == null) {
this.redisManager.init();
c = new RedisCache(this.redisManager, this.keyPrefix);
this.caches.put(name, c);
}
return (Cache)c;
}
public RedisManager getRedisManager() {
return this.redisManager;
}
public void setRedisManager(RedisManager redisManager) {
this.redisManager = redisManager;
}
}