springcache + redis 配置支持缓存ttl失效
package tst; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import lombok.Data; import org.apache.commons.collections4.MapUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.cache.CacheManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.data.redis.cache.RedisCacheConfiguration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.GenericToStringSerializer; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializationContext; import javax.annotation.Resource; import java.time.Duration; import java.util.HashMap; @Data @Configuration @ConfigurationProperties(prefix = "spring.cache.redis") public class RedisConfig { //如果为空默认为12个小时 @Value("${spring.cache.redis.time-to-live:43200000}") private Long redisKeyTtl; private HashMap<String, Long> customTtl; @Resource private RedisTemplate redisTemplate; /** * 默认的字符串序列画 * * @param factory 工厂类 * @return */ @Primary @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(factory); //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值 // RedisSerializer<?> stringSerializer = new StringRedisSerializer(); GenericToStringSerializer<String> stringSerializer = new GenericToStringSerializer<>(String.class); //key序列化 redisTemplate.setKeySerializer(stringSerializer); //value序列化 redisTemplate.setValueSerializer(jacksonSerializer()); //Hash key序列化 redisTemplate.setHashKeySerializer(stringSerializer); //Hash value序列化 redisTemplate.setHashValueSerializer(jacksonSerializer()); redisTemplate.afterPropertiesSet(); return redisTemplate; } /** * 设置redis的key 为 String, value为json * ttl 默认为12个小时 * * @return */ @Bean public CacheManager cacheManager() { //1.基本配置 RedisCacheConfiguration defaultCacheConfiguration = RedisCacheConfiguration .defaultCacheConfig() // 设置key为String, value 为自动转Json的Object .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(stringSerializer())) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jacksonSerializer())) // 不缓存null .disableCachingNullValues() // 缓存数据保存12小时 .entryTtl(Duration.ofMillis(redisKeyTtl)); //2.构造一个redis缓存管理器 RedisCacheManager.RedisCacheManagerBuilder redisCacheManagerBuilder = RedisCacheManager.RedisCacheManagerBuilder // Redis 连接工厂 .fromConnectionFactory(redisTemplate.getConnectionFactory()) // 缓存配置 .cacheDefaults(defaultCacheConfiguration) // 配置同步修改或删除 put/evict .transactionAware(); //2.1自定义ttl if(MapUtils.isNotEmpty(customTtl)){ customTtl.forEach((k,v)->{ redisCacheManagerBuilder.withCacheConfiguration(k,defaultCacheConfiguration.entryTtl(Duration.ofMillis(v))); }); } return redisCacheManagerBuilder.build(); } /** * 默认的jacksonSerializer * * @return Jackson2JsonRedisSerializer */ private static Jackson2JsonRedisSerializer jacksonSerializer() { Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); //反序列化时候遇到不匹配的属性并不抛出异常 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); jackson2JsonRedisSerializer.setObjectMapper(objectMapper); return jackson2JsonRedisSerializer; } private static GenericToStringSerializer stringSerializer() { return new GenericToStringSerializer<>(String.class); } }
配置文件中
spring: cache: # cache-names: xxx-name type: REDIS redis: time-to-live: 28800000 custom-ttl: { "xxx" : "1000000", "yyy": "6000000"}