|
|
|
|
@ -10,7 +10,14 @@
|
|
|
|
|
|
|
|
|
|
package com.yami.shop.common.config;
|
|
|
|
|
|
|
|
|
|
import com.yami.shop.common.serializer.redis.KryoRedisSerializer;
|
|
|
|
|
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
|
|
|
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
|
|
|
|
import com.fasterxml.jackson.databind.MapperFeature;
|
|
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
|
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
|
|
|
|
import com.fasterxml.jackson.databind.json.JsonMapper;
|
|
|
|
|
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
|
|
|
|
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
|
|
|
|
import org.springframework.cache.CacheManager;
|
|
|
|
|
import org.springframework.cache.annotation.EnableCaching;
|
|
|
|
|
import org.springframework.context.annotation.Bean;
|
|
|
|
|
@ -21,7 +28,9 @@ import org.springframework.data.redis.cache.RedisCacheWriter;
|
|
|
|
|
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
|
|
|
|
import org.springframework.data.redis.core.RedisTemplate;
|
|
|
|
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
|
|
|
|
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
|
|
|
|
|
import org.springframework.data.redis.serializer.RedisSerializationContext;
|
|
|
|
|
import org.springframework.data.redis.serializer.RedisSerializer;
|
|
|
|
|
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
|
|
|
|
|
|
|
|
|
import java.time.Duration;
|
|
|
|
|
@ -37,53 +46,79 @@ import java.util.Map;
|
|
|
|
|
public class RedisCacheConfig {
|
|
|
|
|
|
|
|
|
|
@Bean
|
|
|
|
|
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
|
|
|
|
|
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory, RedisSerializer<Object> redisSerializer) {
|
|
|
|
|
|
|
|
|
|
RedisCacheManager redisCacheManager = new RedisCacheManager(
|
|
|
|
|
RedisCacheManager redisCacheManager = new RedisCacheManager(
|
|
|
|
|
RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory),
|
|
|
|
|
// 默认策略,未配置的 key 会使用这个
|
|
|
|
|
this.getRedisCacheConfigurationWithTtl(3600),
|
|
|
|
|
this.getRedisCacheConfigurationWithTtl(3600,redisSerializer),
|
|
|
|
|
// 指定 key 策略
|
|
|
|
|
this.getRedisCacheConfigurationMap()
|
|
|
|
|
);
|
|
|
|
|
redisCacheManager.setTransactionAware(true);
|
|
|
|
|
this.getRedisCacheConfigurationMap(redisSerializer)
|
|
|
|
|
);
|
|
|
|
|
redisCacheManager.setTransactionAware(true);
|
|
|
|
|
return redisCacheManager;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Map<String, RedisCacheConfiguration> getRedisCacheConfigurationMap() {
|
|
|
|
|
private Map<String, RedisCacheConfiguration> getRedisCacheConfigurationMap(RedisSerializer<Object> redisSerializer) {
|
|
|
|
|
Map<String, RedisCacheConfiguration> redisCacheConfigurationMap = new HashMap<>(16);
|
|
|
|
|
// redisCacheConfigurationMap.put("UserInfoList", this.getRedisCacheConfigurationWithTtl(3000));
|
|
|
|
|
// redisCacheConfigurationMap.put("UserInfoListAnother", this.getRedisCacheConfigurationWithTtl(18000));
|
|
|
|
|
|
|
|
|
|
redisCacheConfigurationMap.put("product", this.getRedisCacheConfigurationWithTtl(1800, redisSerializer));
|
|
|
|
|
return redisCacheConfigurationMap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private RedisCacheConfiguration getRedisCacheConfigurationWithTtl(Integer seconds) {
|
|
|
|
|
private RedisCacheConfiguration getRedisCacheConfigurationWithTtl(Integer seconds,RedisSerializer<Object> redisSerializer) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
|
|
|
|
|
redisCacheConfiguration = redisCacheConfiguration.serializeValuesWith(
|
|
|
|
|
RedisSerializationContext
|
|
|
|
|
.SerializationPair
|
|
|
|
|
.fromSerializer(new KryoRedisSerializer<>())
|
|
|
|
|
.fromSerializer(redisSerializer)
|
|
|
|
|
).entryTtl(Duration.ofSeconds(seconds));
|
|
|
|
|
|
|
|
|
|
return redisCacheConfiguration;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Bean
|
|
|
|
|
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
|
|
|
|
|
KryoRedisSerializer kryoRedisSerializer = new KryoRedisSerializer();
|
|
|
|
|
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory,RedisSerializer<Object> redisSerializer) {
|
|
|
|
|
|
|
|
|
|
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
|
|
|
|
|
redisTemplate.setConnectionFactory(redisConnectionFactory);
|
|
|
|
|
redisTemplate.setKeySerializer(new StringRedisSerializer());
|
|
|
|
|
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
|
|
|
|
|
redisTemplate.setValueSerializer(kryoRedisSerializer);
|
|
|
|
|
redisTemplate.setHashValueSerializer(kryoRedisSerializer);
|
|
|
|
|
redisTemplate.setValueSerializer(redisSerializer);
|
|
|
|
|
redisTemplate.setHashValueSerializer(redisSerializer);
|
|
|
|
|
redisTemplate.setEnableTransactionSupport(false);
|
|
|
|
|
|
|
|
|
|
redisTemplate.afterPropertiesSet();
|
|
|
|
|
return redisTemplate;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 自定义redis序列化的机制,重新定义一个ObjectMapper.防止和MVC的冲突
|
|
|
|
|
* https://juejin.im/post/5e869d426fb9a03c6148c97e
|
|
|
|
|
*/
|
|
|
|
|
@Bean
|
|
|
|
|
public RedisSerializer<Object> redisSerializer() {
|
|
|
|
|
ObjectMapper objectMapper = JsonMapper.builder().disable(MapperFeature.USE_ANNOTATIONS).build();
|
|
|
|
|
// 反序列化时候遇到不匹配的属性并不抛出异常
|
|
|
|
|
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
|
|
|
|
// 序列化时候遇到空对象不抛出异常
|
|
|
|
|
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
|
|
|
|
|
// 反序列化的时候如果是无效子类型,不抛出异常
|
|
|
|
|
objectMapper.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, false);
|
|
|
|
|
// 不使用默认的dateTime进行序列化,
|
|
|
|
|
objectMapper.configure(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS, false);
|
|
|
|
|
// 使用JSR310提供的序列化类,里面包含了大量的JDK8时间序列化类
|
|
|
|
|
objectMapper.registerModule(new JavaTimeModule());
|
|
|
|
|
// 启用反序列化所需的类型信息,在属性中添加@class
|
|
|
|
|
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL,
|
|
|
|
|
JsonTypeInfo.As.PROPERTY);
|
|
|
|
|
// 配置null值的序列化器
|
|
|
|
|
GenericJackson2JsonRedisSerializer.registerNullValueSerializer(objectMapper, null);
|
|
|
|
|
return new GenericJackson2JsonRedisSerializer(objectMapper);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Bean
|
|
|
|
|
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory){
|
|
|
|
|
StringRedisTemplate redisTemplate = new StringRedisTemplate(redisConnectionFactory);
|
|
|
|
|
|