|
@@ -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);
|