一、发现问题
如图在serviceImpl中使用@Cacheable
并且自定义了Jackson2JsonRedisSerializer序列化
但是通过查看redis中缓存的数据发现仍然采用的是JDK的序列化方式
二、问题原因
由于采用的是spring的Cache缓存并且配置的缓存方式为redis,而Cache采取的是直接获取RedisCacheManager,并不是RedisTemplate,所以当我们自定义RedisTemplate的序列化时,并不会被Cache采用,如果我们采用的是RedisTemplate API编程式的缓存处理时,自定义序列化生效。
三、问题解决
问题的解决在于对RedisCacheManager进行序列化配置
@Configuration
@EnableCaching
public class CacheManager_redis {
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory factory) {
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer));
Set cacheNames = new HashSet<>();
cacheNames.add("car");
cacheNames.add("distributor");
ConcurrentHashMap configMap = new ConcurrentHashMap<>();
//有效期6分钟自定义缓存时间
configMap.put("car", config.entryTtl(Duration.ofMinutes(1L)));
//永久 key1 的有效期是永久的
configMap.put("distributor", config);
//需要先初始化缓存名称,再初始化其它的配置。
RedisCacheManager cacheManager = RedisCacheManager.builder(factory).initialCacheNames(cacheNames).withInitialCacheConfigurations(configMap).build();
return cacheManager;
}
}
通过下图,发现已经JSON序列化成功