Browse Source

comon-cache修改

LiTaohong 7 years ago
parent
commit
04ee1cff28

+ 35 - 6
base/common-cache/src/main/java/com/yihu/base/cache/cache/CustomMapCache.java

@ -2,6 +2,9 @@ package com.yihu.base.cache.cache;
import com.yihu.base.cache.config.CacheKeyGenerator;
import com.yihu.base.cache.lock.CacheLock;
import com.yihu.base.cache.support.CacheSupport;
import com.yihu.base.cache.util.ReflectionUtils;
import com.yihu.base.cache.util.SpringContextUtils;
import com.yihu.base.cache.util.ThreadTaskUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.Cache;
@ -17,15 +20,20 @@ import org.springframework.util.Assert;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
public class CustomMapCache extends ConcurrentMapCache{
    @Value("expire-time")
    private Long expireTime;
    @Value("refresh-time")
    private Long refreshTime;
    private Long startTime;
    public Long getStartTime() {
        return startTime;
    }
    public CustomMapCache(String name) {
        super(name);
    }
@ -42,26 +50,47 @@ public class CustomMapCache extends ConcurrentMapCache{
        super(name);
        this.expireTime = expireTime;
        this.refreshTime = refreshTime;
        this.startTime = System.currentTimeMillis();
    }
    private CacheSupport getCacheSupport() {
        return SpringContextUtils.getBean(CacheSupport.class);
    }
    /**
     * 重写get方法,获取到缓存后再次取缓存剩余的时间,如果时间小余我们配置的刷新时间就手动刷新缓存。
     * 为了不影响get的性能,启用后台线程去完成缓存的刷。
     * 并且只放一个线程去刷新数据。
     *
     * 重写get方法,获取到缓存后再次取缓存剩余的时间,如果时间小余我们配置的刷新时间就手动刷新缓存,对于内存缓存,直接移除
     * @param key
     * @return
     */
    @Override
    public ValueWrapper get(Object key) {
        String cacheKey = CacheKeyGenerator.getCacheKey();
        ValueWrapper valueWrapper = this.get(key);
        if (null != valueWrapper) {
            // 刷新缓存数据
            refreshCache(key,cacheKey);
        }
        return valueWrapper;
    }
    /**
     * 刷新缓存数据
     */
    private void refreshCache(Object key, String cacheKeyStr) {
        ConcurrentMap<Object, Object> cacheMap = (ConcurrentMap<Object, Object>) ReflectionUtils.getFieldValue(ConcurrentMapCache.class, "store");
        CustomMapCache customMapCache = (CustomMapCache) cacheMap.get(key);
        Long diffTime = System.currentTimeMillis() - customMapCache.getStartTime();
        if (diffTime >= customMapCache.getExpireTime() || diffTime <= customMapCache.getRefreshTime()) {
            synchronized (cacheMap){
                if (diffTime <= customMapCache.getRefreshTime()) {
                    // 通过获取代理方法信息重新加载缓存数据
                    CustomMapCache.this.getCacheSupport().refreshCacheByKey(customMapCache.getName(), key.toString());
                }
            }
        }
    }
}

+ 3 - 6
base/common-cache/src/main/java/com/yihu/base/cache/cache/CustomRedisCache.java

@ -18,10 +18,8 @@ import org.springframework.util.Assert;
public class CustomRedisCache extends RedisCache{
    @Value("expire-time")
    private Long expireTime;
    @Value("refresh-time")
    private Long refreshTime;
    private RedisOperations redisOperations;
@ -52,14 +50,13 @@ public class CustomRedisCache extends RedisCache{
    /**
     * 重写get方法,获取到缓存后再次取缓存剩余的时间,如果时间小余我们配置的刷新时间就手动刷新缓存。
     * 为了不影响get的性能,启用后台线程去完成缓存的刷。
     * 并且只放一个线程去刷新数据。
     *
     * 为了不影响get的性能,启用后台线程去完成缓存的刷新
     * 并且只开一个线程去刷新数据。
     * @param key
     * @return
     */
    @Override
    public ValueWrapper get(final Object key) {
    public ValueWrapper get(Object key) {
        String cacheKey = CacheKeyGenerator.getCacheKey();
        ValueWrapper valueWrapper = this.get(cacheKey);

+ 1 - 1
base/common-cache/src/main/java/com/yihu/base/cache/manager/CustomCacheManager.java

@ -19,7 +19,7 @@ public interface CustomCacheManager extends CacheManager{
    Long getExpireTime(String cacheName,String[] cacheParams);
    Long getAutoRefreshTime(String[] cacheParams);
    Long getRefreshTime(String[] cacheParams);
}

+ 49 - 13
base/common-cache/src/main/java/com/yihu/base/cache/manager/CustomMapCacheManager.java

@ -1,21 +1,19 @@
package com.yihu.base.cache.manager;
import com.yihu.base.cache.cache.CustomMapCache;
import com.yihu.base.cache.cache.CustomRedisCache;
import com.yihu.base.cache.util.ReflectionUtils;
import com.yihu.base.cache.util.SpringContextUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@Component
public class CustomMapCacheManager extends ConcurrentMapCacheManager implements CustomCacheManager{
    @Value("expire-time")
@ -24,9 +22,11 @@ public class CustomMapCacheManager extends ConcurrentMapCacheManager implements
    @Value("refresh-time")
    private Long refreshTime;
    @Autowired
    private ConcurrentMapCacheManager concurrentMapCacheManager;
    @Autowired
    private DefaultListableBeanFactory beanFactory;
    private static final String SUPER_CACHEMAP = "cacheMap";
    public ConcurrentMapCacheManager getInstance(){
@ -46,18 +46,53 @@ public class CustomMapCacheManager extends ConcurrentMapCacheManager implements
        return null;
    }
    /**
     * 获取过期时间
     * @return
     */
    @Override
    public Long getExpireTime(String cacheName, String[] cacheParams) {
        if(cacheParams.length > 1){
            this.expireTime = Long.parseLong(cacheParams[1]);
        // 有效时间,初始化获取默认的有效时间
        Long expirationSecondTime = null;
        // 设置key有效时间
        if (cacheParams.length > 1) {
            String expirationStr = cacheParams[1];
            if (!StringUtils.isEmpty(expirationStr)) {
                // 支持配置过期时间使用EL表达式读取配置文件时间
                if (expirationStr.contains(MARK)) {
                    expirationStr = beanFactory.resolveEmbeddedValue(expirationStr);
                }
                expirationSecondTime = Long.parseLong(expirationStr);
            }
        }
        return expireTime;
        if(null == expirationSecondTime){
            expirationSecondTime = this.getExpireTime();
        }
        return expirationSecondTime;
    }
    /**
     * 获取自动刷新时间
     * @return
     */
    @Override
    public Long getAutoRefreshTime(String[] cacheParams) {
        if(cacheParams.length > 2){
            this.refreshTime = Long.parseLong(cacheParams[2]);
    public Long getRefreshTime(String[] cacheParams) {
        // 自动刷新时间,默认是0
        Long refreshTime = 0L;
        // 设置自动刷新时间
        if (cacheParams.length > 2) {
            String refreshTimeStr = cacheParams[2];
            if (!StringUtils.isEmpty(refreshTimeStr)) {
                // 支持配置刷新时间使用EL表达式读取配置文件时间
                if (refreshTimeStr.contains(MARK)) {
                    refreshTimeStr = beanFactory.resolveEmbeddedValue(refreshTimeStr);
                }
                refreshTime = Long.parseLong(refreshTimeStr);
            }
        }
        if(null == refreshTime){
            refreshTime = this.getRefreshTime();
        }
        return refreshTime;
    }
@ -73,7 +108,7 @@ public class CustomMapCacheManager extends ConcurrentMapCacheManager implements
        long expireTime = getExpireTime(name,cacheParams);
        //注解里面的刷新时间
        long refreshTime = getAutoRefreshTime(cacheParams);
        long refreshTime = getRefreshTime(cacheParams);
        Object obj =  ReflectionUtils.getFieldValue(getInstance(),SUPER_CACHEMAP);
        if(null != obj && obj instanceof ConcurrentHashMap){
@ -100,6 +135,7 @@ public class CustomMapCacheManager extends ConcurrentMapCacheManager implements
                cache = cacheMap.get(cacheName);
                if(null == cache){
                    cache = createConcurrentMapCache(cacheName,expireTime,refreshTime);
                    cacheMap.put(cacheName,cache);
                }
            }
        }

+ 32 - 31
base/common-cache/src/main/java/com/yihu/base/cache/manager/CustomRedisCacheManager.java

@ -9,38 +9,35 @@ import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.cache.Cache;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.util.concurrent.ConcurrentHashMap;
@Component
public class CustomRedisCacheManager extends RedisCacheManager implements CustomCacheManager{
    private RedisCacheManager redisCacheManager = null;
    @Value("expire-time")
    private Long expireTime;
    @Value("refresh-time")
    private Long refreshTime;
    @Autowired
    private DefaultListableBeanFactory beanFactory;
    private RedisCacheManager redisCacheManager = null;
    //父类存放缓存的cacheMap字段
    private static final String SUPER_CACHEMAP = "cacheMap";
    private static final String SUPER_DYNAMIC = "dynamic";
    /**
     * 父类cacheNullValues字段
     */
    //父类cacheNullValues字段
    private static final String SUPER_CACHENULLVALUES = "cacheNullValues";
    /**
     * 父类updateCacheNames方法
     */
     // 父类updateCacheNames方法
    private static final String SUPER_METHOD_UPDATECACHENAMES = "updateCacheNames";
    @Value("expire-time")
    private Long expireTime;
    @Value("refresh-time")
    private Long refreshTime;
    @Override
    public Long getExpireTime() {
        return expireTime;
@ -51,13 +48,6 @@ public class CustomRedisCacheManager extends RedisCacheManager implements Custom
        return refreshTime;
    }
    public void setExpireTime(Long expireTime) {
        this.expireTime = expireTime;
    }
    public void setRefreshTime(Long refreshTime) {
        this.refreshTime = refreshTime;
    }
    public CustomRedisCacheManager(RedisOperations redisOperations) {
        super(redisOperations);
@ -70,6 +60,11 @@ public class CustomRedisCacheManager extends RedisCacheManager implements Custom
        return redisCacheManager;
    }
    /**
     * 覆盖父类获取cache方法
     * @param name,name为注解上的value,以#分隔,第一个为缓存的名字,第二个为缓存的过期时间,第三个为缓存的自动刷新时间
     * @return
     */
    @Override
    public Cache getCache(String name){
        String[] cacheParams = name.split(CustomCacheManager.SEPARATOR);
@ -77,11 +72,11 @@ public class CustomRedisCacheManager extends RedisCacheManager implements Custom
        if(StringUtils.isEmpty(cacheName)){
            return null;
        }
        //注解里面的过期时间覆盖默认的过期时间
        long expireTime = getExpireTime(name,cacheParams);
        //注解里面的过期时间覆盖默认的过期时间,Redis默认有提供过期时间,如果没有传值,就用配置的默认刷新时间
        Long expireTime = getExpireTime(name,cacheParams);
        //注解里面的刷新时间
        long refreshTime = getAutoRefreshTime(cacheParams);
        //注解里面的刷新时间,如果没有传值,就用配置的默认刷新时间
        Long refreshTime = getRefreshTime(cacheParams);
        Object obj =  ReflectionUtils.getFieldValue(getInstance(),SUPER_CACHEMAP);
        if(null != obj && obj instanceof ConcurrentHashMap){
@ -107,11 +102,13 @@ public class CustomRedisCacheManager extends RedisCacheManager implements Custom
            synchronized (cacheMap){
                cache = cacheMap.get(cacheName);
                if(null == cache){
                    //没有则创建一个cache,带上过期时间和刷新时间
                    cache = getMissingCache(cacheName,expireTime,refreshTime);
                    if(null != cache){
                        cache = decorateCache(cache);
                        cacheMap.put(cacheName,cache);
                        //反射调用父类updateCacheNams方法,同步更新缓存名称集合
                        Class<?>[] parameterTypes = {String.class};
                        Object[] paramters = {cacheName};
                        ReflectionUtils.invokeMethod(getInstance(),SUPER_METHOD_UPDATECACHENAMES,parameterTypes,paramters);
@ -124,11 +121,11 @@ public class CustomRedisCacheManager extends RedisCacheManager implements Custom
    public CustomRedisCache getMissingCache(String cacheName, long expirationSecondTime, long preloadSecondTime) {
    public CustomRedisCache getMissingCache(String cacheName, long expirationSecondTime, long refreshTime) {
        Boolean dynamic = (Boolean) ReflectionUtils.getFieldValue(getInstance(),SUPER_DYNAMIC);
        Boolean cacheNullValues = (Boolean) ReflectionUtils.getFieldValue(getInstance(), SUPER_CACHENULLVALUES);
        return dynamic ? new CustomRedisCache(cacheName, (this.isUsePrefix() ? this.getCachePrefix().prefix(cacheName) : null),
                this.getRedisOperations(), expirationSecondTime, preloadSecondTime, cacheNullValues) : null;
                this.getRedisOperations(), expirationSecondTime, refreshTime, cacheNullValues) : null;
    }
@ -152,7 +149,9 @@ public class CustomRedisCacheManager extends RedisCacheManager implements Custom
                expirationSecondTime = Long.parseLong(expirationStr);
            }
        }
        if(null == expirationSecondTime){
            expirationSecondTime = this.getExpireTime();
        }
        return expirationSecondTime;
    }
@ -161,7 +160,7 @@ public class CustomRedisCacheManager extends RedisCacheManager implements Custom
     * @return
     */
    @Override
    public Long getAutoRefreshTime(String[] cacheParams) {
    public Long getRefreshTime(String[] cacheParams) {
        // 自动刷新时间,默认是0
        Long refreshTime = 0L;
        // 设置自动刷新时间
@ -175,7 +174,9 @@ public class CustomRedisCacheManager extends RedisCacheManager implements Custom
                refreshTime = Long.parseLong(preloadStr);
            }
        }
        if(null == refreshTime){
            refreshTime = this.getRefreshTime();
        }
        return refreshTime;
    }
}

+ 0 - 23
base/common-cache/src/main/java/com/yihu/base/cache/support/CacheSupportImpl.java

@ -14,11 +14,6 @@ import java.util.concurrent.ConcurrentHashMap;
@Component
public class CacheSupportImpl implements CacheSupport {
    // 记录缓存执行方法信息的容器。
    public Map<String,Set<CacheInvocation>> cacheInvocationMap = new ConcurrentHashMap<>();
    @Autowired
    private CustomCacheManager customCacheManager;
    /**
     * 根据name获取cache列表
@ -80,24 +75,6 @@ public class CacheSupportImpl implements CacheSupport {
        return object;
    }
    public void refreshCache(String cacheName,CacheInvocation cacheInvocation){
        boolean invocation;
        Object computed = null;
        try {
            computed = invoke(cacheInvocation);
            invocation = true;
        }catch (Exception e){
            invocation = false;
            e.printStackTrace();
        }
        if(invocation){
            if(!CollectionUtils.isEmpty(cacheInvocationMap.get(cacheName))){
                Cache cache = customCacheManager.getCache(cacheName);
                cache.put(cacheInvocation.getKey(),computed);
            }
        }
    }
    @Override
    public void registerInvocation(Object invokedBean, Method invokedMethod, Class[] invocationParamTypes, Object[] invocationArgs, Set<String> annoationCacheNames, String cacheKey) {

+ 21 - 8
base/common-cache/src/main/java/com/yihu/base/cache/support/MapCacheSupportImpl.java

@ -3,15 +3,23 @@ package com.yihu.base.cache.support;
import com.yihu.base.cache.cache.CustomMapCache;
import com.yihu.base.cache.config.CacheKeyGenerator;
import com.yihu.base.cache.manager.CustomCacheManager;
import com.yihu.base.cache.util.ReflectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.concurrent.ConcurrentMapCache;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@Component
public class MapCacheSupportImpl extends CacheSupportImpl implements CacheSupport {
    private ConcurrentMap<String,Object> invocationMap = new ConcurrentHashMap<>();
    @Autowired
    private CustomCacheManager customCacheManager;
@ -19,33 +27,38 @@ public class MapCacheSupportImpl extends CacheSupportImpl implements CacheSuppor
    public void registerInvocation(Object invokedBean, Method invokedMethod, Class[] invocationParamTypes, Object[] invocationArgs, Set<String> annoationCacheNames, String cacheKey) {
        Collection<? extends Cache> caches = getCache(annoationCacheNames);
        CacheInvocation cacheInvocation = new CacheInvocation(CacheKeyGenerator.getCacheKey(),invokedBean,invokedMethod,invocationArgs,invocationParamTypes);
        for(Cache cache:caches){
            if(cache instanceof CustomMapCache){
                CustomMapCache customMapCache = (CustomMapCache)cache;
                Long diffTime = System.currentTimeMillis() - customMapCache.getStartTime();
                if(diffTime >= customMapCache.getExpireTime() || diffTime <= customMapCache.getRefreshTime()){
                    invocationMap.put(cacheKey,cacheInvocation);
                }
            }
        }
    }
    @Override
    public void refreshCacheByKey(String cacheName, String cacheKey) {
//        RedisTemplate redisTemplate = RedisTemplateUtils.getRedisTemplate(redisConnectionFactory);
//        CacheInvocation cacheInvocation = (CacheInvocation)redisTemplate.opsForValue().get(cacheKey);
//        if(null != cacheInvocation){
//            refreshCache(cacheInvocation,cacheName);
//        }
        CacheInvocation cacheInvocation = (CacheInvocation)invocationMap.get(cacheKey);
        if(null != cacheInvocation){
            refreshCache(cacheInvocation,cacheName);
        }
    }
    private void refreshCache(CacheInvocation cacheInvocation,String cacheName){
        Object computed = invoke(cacheInvocation);
        //获取缓存对象
//        ConcurrentMapCacheManager concurrentMapCacheManager = new ConcurrentMapCacheManager();
        Cache cache = customCacheManager.getCache(cacheName);
        //更新缓存
        cache.put(cacheInvocation.getKey(),computed);
        CustomMapCache customMapCache = (CustomMapCache)cache;
        invocationMap.remove(customMapCache.getName());
        ConcurrentMap<Object, Object> cacheMap = (ConcurrentMap<Object, Object>) ReflectionUtils.getFieldValue(ConcurrentMapCache.class, "store");
        cacheMap.remove(customMapCache.getName());
    }
}

+ 2 - 5
base/common-cache/src/main/java/com/yihu/base/cache/support/RedisCacheSupportImpl.java

@ -20,9 +20,6 @@ public class RedisCacheSupportImpl extends CacheSupportImpl implements CacheSupp
    @Autowired
    private CustomCacheManager customCacheManager;
    @Autowired
    private CacheKeyGenerator cacheKeyGenerator;
    @Autowired
    private RedisConnectionFactory redisConnectionFactory;
@ -44,11 +41,11 @@ public class RedisCacheSupportImpl extends CacheSupportImpl implements CacheSupp
        RedisTemplate redisTemplate = RedisTemplateUtils.getRedisTemplate(redisConnectionFactory);
        CacheInvocation cacheInvocation = (CacheInvocation)redisTemplate.opsForValue().get(cacheKey);
        if(null != cacheInvocation){
            refreshCache(cacheInvocation,cacheName);
            refreshCache(cacheName,cacheInvocation);
        }
    }
    private void refreshCache(CacheInvocation cacheInvocation,String cacheName){
    public void refreshCache(String cacheName,CacheInvocation cacheInvocation){
        Object computed = invoke(cacheInvocation);
        //获取缓存对象
        Cache cache = customCacheManager.getCache(cacheName);