jiangping
2023-09-05 7396f1b61c80d13aefb42305c2db6b0c93bbe56e
server/src/main/java/com/doumee/config/shiro/ShiroCache.java
@@ -1,34 +1,38 @@
package com.doumee.config.shiro;
import com.doumee.service.proxy.CacheProxy;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheException;
import org.springframework.beans.factory.annotation.Autowired;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.CollectionUtils;
import org.springframework.context.annotation.Scope;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.SerializationException;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
 * Shiro缓存
 * @author Eva.Caesar Liu
 * @date 2023/02/14 11:14
 * @date 2023/04/17 12:11
 */
@Scope(value = "prototype")
@Slf4j
@Component
public class ShiroCache implements Cache<Object, Serializable> {
    private String keyPrefix = "";
    private String keyPrefix = "ProSelect";
    @Autowired
    private CacheProxy<Object, Serializable> cacheProxy;
    @Resource(name="sessionRedisTemplate")
    private RedisTemplate<Object, Serializable> redisTemplate;
    public ShiroCache () {
        log.debug("ShiroCache: new, keyPrefix = [" + keyPrefix + "]");
@@ -44,7 +48,7 @@
        if (key == null) {
            return null;
        }
        return cacheProxy.get(getKey(key));
        return redisTemplate.opsForValue().get(getKey(key));
    }
    @Override
@@ -52,7 +56,7 @@
        if (key == null) {
            return null;
        }
        cacheProxy.put(getKey(key), value);
        redisTemplate.opsForValue().set(getKey(key), value);
        return value;
    }
@@ -60,14 +64,14 @@
        if (key == null) {
            return null;
        }
        cacheProxy.put(getKey(key), value, timeout);
        redisTemplate.opsForValue().set(getKey(key), value, timeout, TimeUnit.SECONDS);
        return value;
    }
    @Override
    public void clear() throws CacheException {
        Set<Object> keys = this.keys();
        cacheProxy.remove(keys);
        redisTemplate.delete(keys);
    }
    @Override
@@ -77,7 +81,7 @@
    @Override
    public Set<Object> keys() {
        Set<Object> keys = cacheProxy.keys(keyPrefix + "*");
        Set<Object> keys = redisTemplate.keys(keyPrefix + "*");
        if (CollectionUtils.isEmpty(keys)) {
            return Collections.emptySet();
        }
@@ -92,7 +96,7 @@
            return values;
        }
        for (Object k : keys) {
            values.add(cacheProxy.get(k));
            values.add(redisTemplate.opsForValue().get(k));
        }
        return values;
    }
@@ -103,11 +107,53 @@
            return null;
        }
        Serializable value = this.get(getKey(key));
        cacheProxy.remove(getKey(key));
        redisTemplate.delete(getKey(key));
        return value;
    }
    private Object getKey (Object key) {
        if (key instanceof PrincipalCollection) {
            return this.keyPrefix + getRedisKeyFromPrincipalIdField((PrincipalCollection)key);
        }
        return (key instanceof String ? (this.keyPrefix + key) : key);
    }
    /**
     * 获取redis cache key
     */
    private String getRedisKeyFromPrincipalIdField(PrincipalCollection key) {
        Object principalObject = key.getPrimaryPrincipal();
        if (principalObject instanceof String) {
            return principalObject.toString();
        } else {
            Method pincipalIdGetter = this.getPrincipalIdGetter(principalObject);
            return this.getIdObj(principalObject, pincipalIdGetter);
        }
    }
    private Method getPrincipalIdGetter(Object principalObject) {
        Method pincipalIdGetter;
        String principalIdMethodName = this.getPrincipalIdMethodName();
        try {
            pincipalIdGetter = principalObject.getClass().getMethod(principalIdMethodName);
            return pincipalIdGetter;
        } catch (NoSuchMethodException e) {
            throw new SerializationException(e.getMessage(), e);
        }
    }
    private String getIdObj(Object principalObject, Method pincipalIdGetter) {
        try {
            Object idObj = pincipalIdGetter.invoke(principalObject);
            String redisKey = idObj.toString();
            return redisKey;
        } catch (Exception e) {
            throw new SerializationException(e.getMessage(), e);
        }
    }
    private String getPrincipalIdMethodName() {
        return "getId";
    }
}