提交 9d3aa398 编写于 作者: zhouweidong's avatar zhouweidong

补充缓存开关

上级 575fcb58
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
package ${pub.getPKGCodeName()}.util.cache;
import com.github.benmanes.caffeine.cache.CaffeineSpec;
import ${pub.getPKGCodeName()}.util.cache.cacheManager.CaffeineCacheManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.util.StringUtils;
/**
* Caffeine缓存配置类
*/
@EnableCaching
@Configuration
@EnableConfigurationProperties(CacheProperties.class)
@ConditionalOnProperty("ibiz.enableCaffeineCache")
public class CaffeineCacheConfig {
@Autowired
private CacheProperties cacheProperties;
@Autowired
private CaffeineCacheManager caffeineCacheManager;
@Bean
@Primary
public CacheManager cacheManager() {
String specification = cacheProperties.getCaffeine().getSpec();
if (StringUtils.hasText(specification)) {
caffeineCacheManager.setCaffeineSpec(CaffeineSpec.parse(specification));
}
return caffeineCacheManager;
}
}
\ No newline at end of file
......@@ -8,15 +8,16 @@ import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.benmanes.caffeine.cache.CaffeineSpec;
import ${pub.getPKGCodeName()}.util.enums.RedisChannelTopic;
import ${pub.getPKGCodeName()}.util.cache.layering.LayeringCacheManager;
import ${pub.getPKGCodeName()}.util.cache.cacheManager.LayeringCacheManager;
import ${pub.getPKGCodeName()}.util.cache.redis.KryoRedisSerializer;
import ${pub.getPKGCodeName()}.util.cache.redis.StringRedisSerializer;
import ${pub.getPKGCodeName()}.util.cache.setting.FirstCacheSetting;
import ${pub.getPKGCodeName()}.util.enums.RedisChannelTopic;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
......@@ -24,16 +25,11 @@ import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Profile;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.util.StringUtils;
import java.util.HashMap;
import java.util.Map;
/**
* 缓存配置类
......@@ -43,9 +39,17 @@ import java.util.Map;
@EnableCaching
@Configuration
@EnableConfigurationProperties(CacheProperties.class)
@ConditionalOnProperty("ibiz.enableCache")
public class CacheConfig {
@ConditionalOnProperty("ibiz.enableRedisCache")
public class RedisCacheConfig {
@Autowired
private RedisCacheWriter redisCacheWriter;
@Autowired
private RedisCacheConfiguration configuration;
@Autowired
LayeringCacheManager layeringCacheManager;
@Autowired
private CacheProperties cacheProperties;
@Bean
public RedisCacheManager redisCacheManager(RedisConnectionFactory connectionFactory) {
return RedisCacheManager.create(connectionFactory);
......@@ -57,12 +61,6 @@ public class CacheConfig {
return redisCacheWriter;
}
@Autowired
private RedisCacheWriter redisCacheWriter;
@Autowired
private RedisCacheConfiguration configuration;
/**
* 重写Redis序列化方式,使用Json方式:
* 当我们的数据存储到Redis的时候,我们的键(key)和值(value)都是通过Spring提供的Serializer序列化到数据库的。RedisTemplate默认使用的是JdkSerializationRedisSerializerStringRedisTemplate默认使用的是StringRedisSerializer
......@@ -92,41 +90,35 @@ public class CacheConfig {
return redisTemplate;
}
@Bean
@Primary
public CacheManager cacheManager(RedisTemplate<String, Object> redisTemplate) {
LayeringCacheManager layeringCacheManager = new LayeringCacheManager(redisTemplate);
setFirstCacheConfig(layeringCacheManager);//Caffeine缓存设置
layeringCacheManager.setAllowNullValues(true); //允许存null,防止缓存击穿
public CacheManager cacheManager() {
setCaffeineCacheConfig(layeringCacheManager);//Caffeine缓存设置
layeringCacheManager.setRedisCacheWriter(redisCacheWriter);
layeringCacheManager.setRedisConfiguration(configuration);
return layeringCacheManager;
}
@Autowired
private CacheProperties cacheProperties;
private void setFirstCacheConfig(LayeringCacheManager layeringCacheManager) {
private void setCaffeineCacheConfig(LayeringCacheManager layeringCacheManager) {
String specification = cacheProperties.getCaffeine().getSpec();
if (StringUtils.hasText(specification)) {
layeringCacheManager.setCaffeineSpec(CaffeineSpec.parse(specification));
}
Map<String, FirstCacheSetting> firstCacheSettings = new HashMap<>();
layeringCacheManager.setFirstCacheSettings(firstCacheSettings);
}
<#--/**-->
<#--* 监听redis指定频道-->
<#--* @param redisConnectionFactory-->
<#--* @param messageListener-->
<#--* @return-->
<#--*/-->
<#--@Bean-->
<#--RedisMessageListenerContainer redisContainer(RedisConnectionFactory redisConnectionFactory, MessageListenerAdapter messageListener) {-->
<#--final RedisMessageListenerContainer container = new RedisMessageListenerContainer();-->
<#--container.setConnectionFactory(redisConnectionFactory);-->
<#--container.addMessageListener(messageListener, RedisChannelTopic.REDIS_CACHE_DELETE_TOPIC.getChannelTopic());-->
<#--container.addMessageListener(messageListener, RedisChannelTopic.REDIS_CACHE_CLEAR_TOPIC.getChannelTopic());-->
<#--return container;-->
<#--}-->
/**
* 监听redis指定频道
* @param redisConnectionFactory
* @param messageListener
* @return
*/
@Bean
RedisMessageListenerContainer redisContainer(RedisConnectionFactory redisConnectionFactory, MessageListenerAdapter messageListener) {
final RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(redisConnectionFactory);
container.addMessageListener(messageListener, RedisChannelTopic.REDIS_CACHE_DELETE_TOPIC.getChannelTopic());
container.addMessageListener(messageListener, RedisChannelTopic.REDIS_CACHE_CLEAR_TOPIC.getChannelTopic());
return container;
}
}
\ No newline at end of file
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
package ${pub.getPKGCodeName()}.util.cache.cache;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheWriter;
/**
* 自定义的redis缓存
*/
public class CusRedisCache extends RedisCache {
public CusRedisCache(String name, RedisCacheWriter redisCacheWriter, RedisCacheConfiguration configuration) {
super(name, redisCacheWriter, configuration);
}
}
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
package ${pub.getPKGCodeName()}.util.cache.layering;
package ${pub.getPKGCodeName()}.util.cache.cache;
import ${pub.getPKGCodeName()}.util.enums.RedisChannelTopic;
import ${pub.getPKGCodeName()}.util.cache.listener.RedisPublisher;
import ${pub.getPKGCodeName()}.util.cache.redis.CustomizedRedisCache;
import ${pub.getPKGCodeName()}.util.enums.RedisChannelTopic;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.caffeine.CaffeineCache;
......@@ -18,55 +17,41 @@ import org.springframework.data.redis.core.RedisOperations;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
/**
* 缓存分层类
* 1级缓存为caffeine
* 2级缓存为redis
*/
public class LayeringCache extends AbstractValueAdaptingCache {
Logger logger = LoggerFactory.getLogger(LayeringCache.class);
Logger logger = LoggerFactory.getLogger(LayeringCache.class);
/**
* 缓存的名称
*/
private final String name;
/**
* 是否使用一级缓存
*/
private boolean usedFirstCache = true;
/**
* redi缓存
* redis缓存
*/
private RedisCache redisCache;
/**
* Caffeine缓存
*/
private final CaffeineCache caffeineCache;
RedisOperations<? extends Object, ? extends Object> redisOperations;
/**
* @param name 缓存名称
* @param allowNullValues 是否允许存NULL,默认是false
* @param usedFirstCache 是否使用一级缓存,默认是true
* @param caffeineCache Caffeine缓存
* redis消息发布
*/
public LayeringCache(String name , boolean allowNullValues,RedisOperations redisOperations, boolean usedFirstCache, com.github.benmanes.caffeine.cache.Cache<Object, Object> caffeineCache,
RedisOperations<? extends Object, ? extends Object> redisOperations;
public LayeringCache(String name ,RedisOperations redisOperations, com.github.benmanes.caffeine.cache.Cache<Object, Object> caffeineCache,
RedisCacheWriter redisCacheWriter, RedisCacheConfiguration configuration) {
super(allowNullValues);
super(true);
this.name = name;
this.usedFirstCache = usedFirstCache;
this.redisCache = new CustomizedRedisCache(name, redisCacheWriter, configuration);
this.caffeineCache = new CaffeineCache(name, caffeineCache, allowNullValues);
this.redisCache = new CusRedisCache(name, redisCacheWriter, configuration);
this.caffeineCache = new CaffeineCache(name, caffeineCache, true);
this.redisOperations=redisOperations;
}
public CaffeineCache getFirstCache() {
return this.caffeineCache;
}
@Override
public String getName() {
return this.name;
......@@ -79,13 +64,9 @@ public class LayeringCache extends AbstractValueAdaptingCache {
@Override
public ValueWrapper get(Object key) {
ValueWrapper wrapper = null;
if (usedFirstCache) {
// 查询一级缓存
wrapper = caffeineCache.get(key);
logger.debug("查询一级缓存 key:{},value:{}", key,wrapper);
}
// 查询一级缓存
ValueWrapper wrapper = caffeineCache.get(key);
logger.debug("查询一级缓存 key:{},value:{}", key,wrapper);
if (wrapper == null) {
// 查询二级缓存
wrapper = redisCache.get(key);
......@@ -97,12 +78,9 @@ public class LayeringCache extends AbstractValueAdaptingCache {
@Override
public <T> T get(Object key, Class<T> type) {
T value = null;
if (usedFirstCache) {
// 查询一级缓存
value = caffeineCache.get(key, type);
logger.debug("查询一级缓存 key:{}", key);
}
// 查询一级缓存
T value = caffeineCache.get(key, type);
logger.debug("查询一级缓存 key:{}", key);
if (value == null) {
// 查询二级缓存
value = redisCache.get(key, type);
......@@ -115,15 +93,12 @@ public class LayeringCache extends AbstractValueAdaptingCache {
@SuppressWarnings("unchecked")
@Override
public <T> T get(Object key, Callable<T> valueLoader) {
T value = null;
if (usedFirstCache) {
// 查询一级缓存,如果一级缓存没有值则调用getForSecondaryCache(k, valueLoader)查询二级缓存
value = (T) caffeineCache.getNativeCache().get(key, k -> getForSecondaryCache(k, valueLoader));
} else {
// 查询一级缓存,如果一级缓存没有值则调用getForSecondaryCache(k, valueLoader)查询二级缓存
T value = (T) caffeineCache.getNativeCache().get(key, k -> getSecondCache(k, valueLoader));
if(value==null) {
// 直接查询二级缓存
value = (T) getForSecondaryCache(key, valueLoader);
value = (T) getSecondCache(key, valueLoader);
}
if (value instanceof NullValue) {
return null;
}
......@@ -132,53 +107,42 @@ public class LayeringCache extends AbstractValueAdaptingCache {
@Override
public void put(Object key, Object value) {
if (usedFirstCache) {
caffeineCache.put(key, value);
}
caffeineCache.put(key, value);
redisCache.put(key, value);
}
@Override
public ValueWrapper putIfAbsent(Object key, Object value) {
if (usedFirstCache) {
caffeineCache.putIfAbsent(key, value);
}
caffeineCache.putIfAbsent(key, value);
return redisCache.putIfAbsent(key, value);
}
@Override
public void evict(Object key) {
redisCache.evict(key); //清除redis中的二级缓存
if (usedFirstCache) {
caffeineCache.evict(key);//清除本机一级缓存
Map<String, Object> message = new HashMap<>();
message.put("cacheName", name);
message.put("key", key);
RedisPublisher redisPublisher = new RedisPublisher(redisOperations, RedisChannelTopic.REDIS_CACHE_DELETE_TOPIC.getChannelTopic());// 创建redis发布者
redisPublisher.publisher(message);//发布消息,清除其它集群机器中的一级缓存
}
caffeineCache.evict(key);//清除本机一级缓存
Map<String, Object> message = new HashMap<>();
message.put("cacheName", name);
message.put("key", key);
RedisPublisher redisPublisher = new RedisPublisher(redisOperations, RedisChannelTopic.REDIS_CACHE_DELETE_TOPIC.getChannelTopic());// 创建redis发布者
redisPublisher.publisher(message);//发布消息,清除其它集群机器中的一级缓存
logger.debug(String.format("清除二级缓存数据[%s]", key));
}
@Override
public void clear() {
redisCache.clear(); //清除redis中的二级缓存
if (usedFirstCache) {
caffeineCache.clear();//清除本机一级缓存
Map<String, Object> message = new HashMap<>();
message.put("cacheName", name);
RedisPublisher redisPublisher = new RedisPublisher(redisOperations, RedisChannelTopic.REDIS_CACHE_CLEAR_TOPIC.getChannelTopic());// 创建redis发布者
redisPublisher.publisher(message);//发布消息,清除其它集群机器中的一级缓存
}
caffeineCache.clear();//清除本机一级缓存
Map<String, Object> message = new HashMap<>();
message.put("cacheName", name);
RedisPublisher redisPublisher = new RedisPublisher(redisOperations, RedisChannelTopic.REDIS_CACHE_CLEAR_TOPIC.getChannelTopic());// 创建redis发布者
redisPublisher.publisher(message);//发布消息,清除其它集群机器中的一级缓存
}
@Override
protected Object lookup(Object key) {
Object value = null;
if (usedFirstCache) {
value = caffeineCache.get(key);
logger.debug("查询一级缓存 key:{}", key);
}
Object value = caffeineCache.get(key);
logger.debug("查询一级缓存 key:{}", key);
if (value == null) {
value = redisCache.get(key);
logger.debug("查询二级缓存 key:{}", key);
......@@ -192,9 +156,17 @@ public class LayeringCache extends AbstractValueAdaptingCache {
* @param valueLoader
* @return
*/
private <T> Object getForSecondaryCache(Object key, Callable<T> valueLoader) {
private <T> Object getSecondCache(Object key, Callable<T> valueLoader) {
T value = redisCache.get(key, valueLoader);
logger.debug("查询二级缓存 key:{}", key);
return toStoreValue(value);
}
/**
* 获取caffeine缓存
* @return
*/
public CaffeineCache getFirstCache() {
return this.caffeineCache;
}
}
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
package ${pub.getPKGCodeName()}.util.cache.cacheManager;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.CaffeineSpec;
import lombok.Data;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
/**
* Caffeine本地缓存
*/
@Data
@Component
@ConditionalOnProperty("ibiz.enableCaffeineCache")
public class CaffeineCacheManager implements CacheManager {
private static final int DEFAULT_EXPIRE_AFTER_WRITE = 1;
private static final int DEFAULT_INITIAL_CAPACITY = 5;
private static final int DEFAULT_MAXIMUM_SIZE = 1_000;
private final ConcurrentMap<String, Cache> cacheMap = new ConcurrentHashMap<String, Cache>(16);
/**
* 缓存默认设置
*/
private Caffeine<Object, Object> cacheBuilder = Caffeine.newBuilder()
.expireAfterAccess(DEFAULT_EXPIRE_AFTER_WRITE, TimeUnit.HOURS)
.initialCapacity(DEFAULT_INITIAL_CAPACITY)
.maximumSize(DEFAULT_MAXIMUM_SIZE);
/**
* 获取缓存对象
* @param name
* @return
*/
@Override
public Cache getCache(String name) {
Cache cache = this.cacheMap.get(name);
if (cache == null) {
synchronized (this.cacheMap) {
cache = this.cacheMap.get(name);
if (cache == null) {
cache = createCache(name);
this.cacheMap.put(name, cache);
}
}
}
return cache;
}
/**
* 获取缓存名
* @return
*/
@Override
public Collection<String> getCacheNames() {
return Collections.unmodifiableSet(this.cacheMap.keySet());
}
/**
* 创建缓存
* @param name
* @return
*/
protected Cache createCache(String name) {
return new CaffeineCache(name, this.cacheBuilder.build(), true);
}
/**
* 缓存配置[缓存容量大小、时长等]
* @param caffeineSpec
*/
public void setCaffeineSpec(CaffeineSpec caffeineSpec) {
Caffeine<Object, Object> cacheBuilder = Caffeine.from(caffeineSpec);
if (!ObjectUtils.nullSafeEquals(this.cacheBuilder, cacheBuilder)) {
this.cacheBuilder = cacheBuilder;
refreshKnownCaches();
}
}
/**
* 使用该CacheManager的当前状态重新创建已知的缓存。
*/
private void refreshKnownCaches() {
for (Map.Entry<String, Cache> entry : this.cacheMap.entrySet()) {
entry.setValue(createCache(entry.getKey()));
}
}
}
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
package ${pub.getPKGCodeName()}.util.cache.layering;
package ${pub.getPKGCodeName()}.util.cache.cacheManager;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.CaffeineSpec;
import ${pub.getPKGCodeName()}.util.cache.setting.FirstCacheSetting;
import ${pub.getPKGCodeName()}.util.cache.setting.SecondaryCacheSetting;
import lombok.Data;
import ${pub.getPKGCodeName()}.util.cache.cache.LayeringCache;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import java.util.Collection;
import java.util.Collections;
......@@ -22,7 +22,6 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
import org.springframework.util.StringUtils;
/**
* 缓存分层类
......@@ -30,40 +29,20 @@ import org.springframework.util.StringUtils;
* 2级缓存为redis
*/
@Data
@Component
@ConditionalOnProperty("ibiz.enableRedisCache")
public class LayeringCacheManager implements CacheManager {
static final int DEFAULT_EXPIRE_AFTER_WRITE = 2;
static final int DEFAULT_INITIAL_CAPACITY = 5;
static final int DEFAULT_MAXIMUM_SIZE = 1_000;
private final ConcurrentMap<String, Cache> cacheMap = new ConcurrentHashMap<String, Cache>(16);
/**
* 一级缓存配置
*/
private Map<String, FirstCacheSetting> firstCacheSettings = null;
/**
* 二级缓存配置
*/
private Map<String, SecondaryCacheSetting> secondaryCacheSettings = null;
private static final int DEFAULT_EXPIRE_AFTER_WRITE = 1;
private static final int DEFAULT_INITIAL_CAPACITY = 5;
private static final int DEFAULT_MAXIMUM_SIZE = 1_000;
private final ConcurrentMap<String, Cache> cacheMap = new ConcurrentHashMap<String, Cache>(16);
public RedisCacheWriter redisCacheWriter;
public RedisCacheConfiguration redisConfiguration;
public RedisOperations redisOperations;
/**
* 是否允许动态创建缓存,默认是true
*/
private boolean dynamic = true;
/**
* 缓存值是否允许为NULL
*/
private boolean allowNullValues = false;
/**
* expireAfterWrite2 小时
* initialCapacity5
* maximumSize 1_000
* 缓存默认设置
*/
private Caffeine<Object, Object> cacheBuilder = Caffeine.newBuilder()
.expireAfterAccess(DEFAULT_EXPIRE_AFTER_WRITE, TimeUnit.HOURS)
......@@ -82,7 +61,7 @@ public class LayeringCacheManager implements CacheManager {
@Override
public Cache getCache(String name) {
Cache cache = this.cacheMap.get(name);
if (cache == null && this.dynamic) {
if (cache == null) {
synchronized (this.cacheMap) {
cache = this.cacheMap.get(name);
if (cache == null) {
......@@ -100,21 +79,11 @@ public class LayeringCacheManager implements CacheManager {
}
protected Cache createCache(String name) {
return new LayeringCache(name,isAllowNullValues(),this.redisOperations, getUsedFirstCache(name),createNativeCaffeineCache(name),redisCacheWriter,redisConfiguration);
return new LayeringCache(name,this.redisOperations ,this.cacheBuilder.build(),redisCacheWriter,redisConfiguration);
}
/**
* Create a native Caffeine Cache instance for the specified cache name.
*
* @param name the name of the cache
* @return the native Caffeine Cache instance
*/
protected com.github.benmanes.caffeine.cache.Cache<Object, Object> createNativeCaffeineCache(String name) {
return getCaffeine(name).build();
}
/**
* 使用该CacheManager的当前状态重新创建已知的缓存。
* 使用该CacheManager的当前状态重新创建已知的缓存
*/
private void refreshKnownCaches() {
for (Map.Entry<String, Cache> entry : this.cacheMap.entrySet()) {
......@@ -122,48 +91,6 @@ public class LayeringCacheManager implements CacheManager {
}
}
/**
* 设置是否允许Cache的值为null
*
* @param allowNullValues
*/
public void setAllowNullValues(boolean allowNullValues) {
if (this.allowNullValues != allowNullValues) {
this.allowNullValues = allowNullValues;
refreshKnownCaches();
}
}
/**
* 获取是否允许Cache的值为null
*
* @return
*/
public boolean isAllowNullValues() {
return this.allowNullValues;
}
/**
* 根据缓存名称设置一级缓存的有效时间和刷新时间,单位秒
*
* @param firstCacheSettings
*/
public void setFirstCacheSettings(Map<String, FirstCacheSetting> firstCacheSettings) {
this.firstCacheSettings = (!CollectionUtils.isEmpty(firstCacheSettings) ? new ConcurrentHashMap<>(firstCacheSettings) : null);
}
/**
* 获取是否使用一级缓存,默认是true
*/
public boolean getUsedFirstCache(String name) {
SecondaryCacheSetting secondaryCacheSetting = null;
if (!CollectionUtils.isEmpty(secondaryCacheSettings)) {
secondaryCacheSetting = secondaryCacheSettings.get(name);
}
return secondaryCacheSetting != null ? secondaryCacheSetting.getUsedFirstCache() : true;
}
public void setCaffeineSpec(CaffeineSpec caffeineSpec) {
Caffeine<Object, Object> cacheBuilder = Caffeine.from(caffeineSpec);
if (!ObjectUtils.nullSafeEquals(this.cacheBuilder, cacheBuilder)) {
......@@ -171,14 +98,5 @@ public class LayeringCacheManager implements CacheManager {
refreshKnownCaches();
}
}
private Caffeine<Object, Object> getCaffeine(String name) {
if (!CollectionUtils.isEmpty(firstCacheSettings)) {
FirstCacheSetting firstCacheSetting = firstCacheSettings.get(name);
if (firstCacheSetting != null && StringUtils.isEmpty(firstCacheSetting.getCacheSpecification())) {
// 根据缓存名称获取一级缓存配置
return Caffeine.from(CaffeineSpec.parse(firstCacheSetting.getCacheSpecification()));
}
}
return this.cacheBuilder;
}
}
......@@ -3,26 +3,29 @@ TARGET=PSSYSTEM
</#ibiztemplate>
package ${pub.getPKGCodeName()}.util.cache.listener;
import ${pub.getPKGCodeName()}.util.cache.cache.LayeringCache;
import ${pub.getPKGCodeName()}.util.enums.RedisChannelTopic;
import ${pub.getPKGCodeName()}.util.cache.layering.LayeringCache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Profile;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.util.Map;
/**
* redis消息的订阅者
*/
@Profile("prod")
@Component
@ConditionalOnProperty("ibiz.enableRedisCache")
public class RedisMessageListener extends MessageListenerAdapter {
private static final Logger logger = LoggerFactory.getLogger(RedisPublisher.class);
@Autowired
......@@ -41,7 +44,7 @@ public class RedisMessageListener extends MessageListenerAdapter {
map= (Map<String, Object>) result;
}
if(StringUtils.isEmpty(map)|| (!map.containsKey("cacheName"))|| (!map.containsKey("key"))){
logger.info("解析缓存数据失败,无法获取指定值!");
logger.debug("解析缓存数据失败,无法获取指定值!");
return ;
}
logger.debug("redis消息订阅者接收到频道【{}】发布的消息。消息内容:{}", channelTopic.getChannelTopicStr(), result.toString());
......
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
package ${pub.getPKGCodeName()}.util.cache.setting;
import com.github.benmanes.caffeine.cache.CaffeineSpec;
public class FirstCacheSetting {
/**
* 一级缓存配置,配置项请点击这里 {@link CaffeineSpec#configure(String, String)}
* @param cacheSpecification
*/
public FirstCacheSetting(String cacheSpecification) {
this.cacheSpecification = cacheSpecification;
}
private String cacheSpecification;
public String getCacheSpecification() {
return cacheSpecification;
}
}
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
package ${pub.getPKGCodeName()}.util.cache.setting;
public class SecondaryCacheSetting {
/**
* @param expirationSecondTime 设置redis缓存的有效时间,单位秒
* @param preloadSecondTime 设置redis缓存的自动刷新时间,单位秒
*/
public SecondaryCacheSetting(long expirationSecondTime, long preloadSecondTime) {
this.expirationSecondTime = expirationSecondTime;
this.preloadSecondTime = preloadSecondTime;
}
/**
* @param usedFirstCache 是否启用一级缓存,默认true
* @param expirationSecondTime 设置redis缓存的有效时间,单位秒
* @param preloadSecondTime 设置redis缓存的自动刷新时间,单位秒
*/
public SecondaryCacheSetting(boolean usedFirstCache, long expirationSecondTime, long preloadSecondTime) {
this.expirationSecondTime = expirationSecondTime;
this.preloadSecondTime = preloadSecondTime;
this.usedFirstCache = usedFirstCache;
}
/**
* @param expirationSecondTime 设置redis缓存的有效时间,单位秒
* @param preloadSecondTime 设置redis缓存的自动刷新时间,单位秒
* @param forceRefresh 是否使用强制刷新(走数据库),默认false
*/
public SecondaryCacheSetting(long expirationSecondTime, long preloadSecondTime, boolean forceRefresh) {
this.expirationSecondTime = expirationSecondTime;
this.preloadSecondTime = preloadSecondTime;
this.forceRefresh = forceRefresh;
}
/**
* @param expirationSecondTime 设置redis缓存的有效时间,单位秒
* @param preloadSecondTime 设置redis缓存的自动刷新时间,单位秒
* @param usedFirstCache 是否启用一级缓存,默认true
* @param forceRefresh 是否使用强制刷新(走数据库),默认false
*/
public SecondaryCacheSetting(long expirationSecondTime, long preloadSecondTime, boolean usedFirstCache, boolean forceRefresh) {
this.expirationSecondTime = expirationSecondTime;
this.preloadSecondTime = preloadSecondTime;
this.usedFirstCache = usedFirstCache;
this.forceRefresh = forceRefresh;
}
/**
* 缓存有效时间
*/
private long expirationSecondTime;
/**
* 缓存主动在失效前强制刷新缓存的时间
* 单位:秒
*/
private long preloadSecondTime = 0;
/**
* 是否使用一级缓存,默认是true
*/
private boolean usedFirstCache = true;
/**
* 是否使用强刷新(走数据库),默认是false
*/
private boolean forceRefresh = false;
public long getPreloadSecondTime() {
return preloadSecondTime;
}
public long getExpirationSecondTime() {
return expirationSecondTime;
}
public boolean getUsedFirstCache() {
return usedFirstCache;
}
public boolean getForceRefresh() {
return forceRefresh;
}
}
......@@ -124,12 +124,13 @@ ribbon:
ReadTimeout: 60000
ConnectTimeout: 60000
#系统是否开启权限验证、是否开启缓存
<#assign enableCache="false">
#系统是否开启权限验证、是否开启缓存 [本地缓存:enableCaffeineCache=true 或 两级缓存(caffeine+redis):enableRedisCache=true]
ibiz:
enablePermissionValid: false
<#if sys.getPSSystemSetting()?? && sys.getPSSystemSetting().getDataAccCtrlArch()?? && sys.getPSSystemSetting().getDataAccCtrlArch()==1>
enableCache: true
<#else >
enableCache: false
<#assign enableCache="true">
</#if>
enableCaffeineCache: ${enableCache}
#enableRedisCache: ${enableCache}
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册