RedisCache 实现 Cache 接口
代码语言:javascript复制自定义Cache类,主要是将缓存全部交给Redis管理,而不是使用其默认存储体系
package com.ccb.web.shiro;
import com.ccb.web.configs.CsRedisUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import projects.commons.utils.ValidateUtils;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
/**
* Redis Catch
*
* @author zhuyongsheng
* @date 2019/8/13
*/
@Slf4j
@Data
public class RedisCache<K, V> implements Cache<K, V> {
@Autowired
CsRedisUtil redisUtil;
//key前缀
private String keyPrefix = "";
// redis TTL
private int expire = 0;
//存储对象ID名称
private String principalIdFieldName = RedisCacheManager.DEFAULT_PRINCIPAL_ID_FIELD_NAME;
/**
* 初始化
*
* @author zhuyongsheng
* @date 2019/8/15
*/
public RedisCache(String prefix, int expire, String principalIdFieldName) {
if (prefix != null && !"".equals(prefix)) {
this.keyPrefix = prefix;
}
if (expire != -1) {
this.expire = expire;
}
if (principalIdFieldName != null && !"".equals(principalIdFieldName)) {
this.principalIdFieldName = principalIdFieldName;
}
}
/**
* 清空缓存
*
* @author zhuyongsheng
* @date 2019/8/15
*/
@Override
public void clear() throws CacheException {
Set<String> keys = null;
try {
keys = redisUtil.scan(this.keyPrefix "*");
} catch (Exception e) {
log.warn("==clear==获取key失败=={}", e.getMessage());
}
if (keys == null || keys.size() == 0) {
return;
}
for (String key : keys) {
redisUtil.del(key);
}
}
/**
* 根据key获取对象信息
*
* @return V
* @author zhuyongsheng
* @date 2019/8/13
*/
@Override
public V get(K key) throws CacheException {
if (ValidateUtils.isNotNull(key)) {
return null;
}
try {
String redisCacheKey = getRedisCacheKey(key);
Object rawValue = redisUtil.get(redisCacheKey);
if (rawValue == null) {
return null;
}
V value = (V) rawValue;
return value;
} catch (Exception e) {
log.warn("==get==获取key失败=={}", e.getMessage());
throw new CacheException("获取数据失败!");
}
}
@SuppressWarnings("unchecked")
@Override
public Set<K> keys() {
Set<String> keys;
try {
keys = redisUtil.scan(this.keyPrefix "*");
} catch (Exception e) {
log.warn("==keys==获取key失败=={}", e.getMessage());
return Collections.emptySet();
}
if (CollectionUtils.isEmpty(keys)) {
return Collections.emptySet();
}
Set<K> convertedKeys = new HashSet<>();
for (String key : keys) {
try {
convertedKeys.add((K) key);
} catch (Exception e) {
log.warn("==keys==序列化失败=={}", e.getMessage());
}
}
return convertedKeys;
}
/**
* 存放数据
*
* @return V
* @author zhuyongsheng
* @date 2019/8/13
*/
@Override
public V put(K key, V value) throws CacheException {
if (ValidateUtils.isNotNull(key)) {
return value;
}
try {
String redisCacheKey = getRedisCacheKey(key);
redisUtil.set(redisCacheKey, value != null ? (Serializable) value : null, expire);
return value;
} catch (Exception e) {
log.warn("==put==设置key失败=={},key={},value={}}", e.getMessage(), key, value);
throw new CacheException("获取key值失败!");
}
}
/**
* 删除数据
*
* @return V
* @author zhuyongsheng
* @date 2019/8/13
*/
@Override
public V remove(K key) throws CacheException {
if (ValidateUtils.isNotNull(key)) {
return null;
}
try {
String redisCacheKey = getRedisCacheKey(key);
Object rawValue = redisUtil.get(redisCacheKey);
V previous = (V) rawValue;
redisUtil.del(redisCacheKey);
return previous;
} catch (Exception e) {
log.warn("==remove==获取key失败=={}", e.getMessage());
throw new CacheException("删除数据失败!");
}
}
/**
* 获取CacheKey值
*
* @return java.lang.String
* @author zhuyongsheng
* @date 2019/8/13
*/
private String getRedisCacheKey(K key) {
if (ValidateUtils.isNotNull(key)) {
return null;
}
return this.keyPrefix getStringRedisKey(key);
}
/**
* 获取RedisKey
*
* @return java.lang.String
* @author zhuyongsheng
* @date 2019/8/13
*/
private String getStringRedisKey(K key) {
String redisKey;
if (key instanceof PrincipalCollection) {
redisKey = getRedisKeyFromPrincipalIdField((PrincipalCollection) key);
} else {
redisKey = key.toString();
}
return redisKey;
}
private String getRedisKeyFromPrincipalIdField(PrincipalCollection key) {
String redisKey;
Object principalObject = key.getPrimaryPrincipal();
Method pincipalIdGetter = null;
Method[] methods = principalObject.getClass().getDeclaredMethods();
for (Method m : methods) {
if (RedisCacheManager.DEFAULT_PRINCIPAL_ID_FIELD_NAME.equals(this.principalIdFieldName)
&& ("getAuthCacheKey".equals(m.getName()) || "getId".equals(m.getName()))) {
pincipalIdGetter = m;
break;
}
if (m.getName().equals("get" this.principalIdFieldName.substring(0, 1).toUpperCase() this.principalIdFieldName.substring(1))) {
pincipalIdGetter = m;
break;
}
}
if (pincipalIdGetter == null) {
throw new PrincipalInstanceException(principalObject.getClass(), this.principalIdFieldName);
}
try {
Object idObj = pincipalIdGetter.invoke(principalObject);
if (idObj == null) {
throw new PrincipalIdNullException(principalObject.getClass(), this.principalIdFieldName);
}
redisKey = idObj.toString();
} catch (IllegalAccessException | InvocationTargetException e) {
throw new PrincipalInstanceException(principalObject.getClass(), this.principalIdFieldName, e);
}
return redisKey;
}
/**
* 获取数量
*
* @return int
* @author zhuyongsheng
* @date 2019/8/15
*/
@Override
public int size() {
Long longSize = 0L;
try {
longSize = redisUtil.scanSize(this.keyPrefix "*");
} catch (Exception e) {
log.warn("==size==获取key失败=={}", e.getMessage());
}
return longSize.intValue();
}
@SuppressWarnings("unchecked")
@Override
public Collection<V> values() {
Set<String> keys;
try {
keys = redisUtil.scan(this.keyPrefix "*");
} catch (Exception e) {
log.warn("==values==获取key失败=={}", e.getMessage());
return Collections.emptySet();
}
if (CollectionUtils.isEmpty(keys)) {
return Collections.emptySet();
}
List<V> values = new ArrayList<>(keys.size());
for (String key : keys) {
V value = null;
try {
value = (V) redisUtil.get(key);
} catch (Exception e) {
log.warn("==values==获取key失败=={}", e.getMessage());
}
if (value != null) {
values.add(value);
}
}
return Collections.unmodifiableList(values);
}
}