springboot3 + redis 缓存整合 支持@Cacheable 设置Json序列化,并支持按缓存设置缓存时间
创始人
2025-01-11 11:08:25
0

springboot3默认的整合下,缓存时间未指定(默认永不失效),且序列化方式为Jdk的Serializable序列化方式,使用起来略有不便。Serializable序列化方式在序列化ID有变化,或者未指定序列化ID时,类的字段一变化,就会报错反序列化失败。
下面是一个可以指定指定缓存时间,指定默认缓存时间,并且使用JSON序列化方式的集成代码。

引入依赖

                     org.springframework.boot             spring-boot-starter-data-redis                                org.springframework.boot             spring-boot-starter-cache           

设置默认的RedisTemplate

如果项目中是直接使用RedisTmplate来进行缓存的,需要指定RestTemplate的序列化方式,代码如下:

@UtilityClass public class JacksonJsonSerializerUtil {     public static GenericJackson2JsonRedisSerializer getJackson2JsonRedisSerializer() {         var jackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();         jackson2JsonRedisSerializer.configure(objectMapper -> {             // add java8 time module             objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);             objectMapper.activateDefaultTyping(new LaissezFaireSubTypeValidator(),                     ObjectMapper.DefaultTyping.EVERYTHING);             JavaTimeModule javaTimeModule = new JavaTimeModule();             objectMapper.registerModule(javaTimeModule);         });         return jackson2JsonRedisSerializer;     } } 
    @Bean("redisTemplate")     RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) {         RedisTemplate redisTemplate = new RedisTemplate<>();         redisTemplate.setConnectionFactory(connectionFactory);          var jackson2JsonRedisSerializer = JacksonJsonSerializerUtil.getJackson2JsonRedisSerializer();          // 设置value的序列化规则和key的序列化规则         redisTemplate.setKeySerializer(new StringRedisSerializer());         redisTemplate.setHashKeySerializer(new StringRedisSerializer());         redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);         redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);         redisTemplate.afterPropertiesSet();         return redisTemplate;     } 

设置@Cacheable的序列化方式

@Cacheable不使用RedisTemplate,因此上面的定义是无效的,它直接使用CacheManager,因此我们需要自定义。spring提供了自定义的RedisCacheManagerBuilderCustomizer来支持自定义,我们实现它,并将它注入到spring容器中就可以了。

public class MyRedisCacheManagerBuilderSerialCustomizer implements RedisCacheManagerBuilderCustomizer {     @Override     public void customize(RedisCacheManager.RedisCacheManagerBuilder builder) {         RedisSerializer stringRedisSerializer = new StringRedisSerializer();          var jackson2JsonRedisSerializer = getJackson2JsonRedisSerializer();         var configuration = builder.cacheDefaults()                 .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(stringRedisSerializer))                 .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer));          builder.cacheDefaults(configuration);         var configuredCaches = builder.getConfiguredCaches();          // 针对有的缓存存在自定义配置的情况,读取所有缓存的配置,设置序列化方法         for (String configuredCache : configuredCaches) {             var cacheConfig = builder.getCacheConfigurationFor(configuredCache);             cacheConfig.ifPresent(config -> {                 var newConfig = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(stringRedisSerializer))                         .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer));                 builder.withCacheConfiguration(configuredCache, newConfig);             });         }     } }  
// 注入到spring容器中     @Bean     MyRedisCacheManagerBuilderSerialCustomizer myRedisCacheManagerBuilderSerialCustomizer() {         return new MyRedisCacheManagerBuilderSerialCustomizer();     } 

自定义缓存的过期时间,以及默认过期时间

我们自定义一个配置来支持设置过期时间,配置如下:

myservice:   redis:     # 采用ISO-8601时间格式。格式为:PnDTnHnMnS   (n为个数)     #例如:P1Y2M3DT4H5M6.7S = 1年2个月3天4小时5分钟6.7秒     default-expire-time: PT30M     cache-and-expires:       - cache-name: test         expire-time: PT10M 
@Data public class CacheAndExpire {     private String cacheName;     private Duration expireTime; }  
@Slf4j public class MyRedisCacheManagerBuilderCustomizer implements RedisCacheManagerBuilderCustomizer {     private final MyRedisConfig myRedisConfig;      public MyRedisCacheManagerBuilderCustomizer(MyRedisConfig myRedisConfig) {         this.myRedisConfig = myRedisConfig;     }      @Override     public void customize(RedisCacheManager.RedisCacheManagerBuilder builder) {         log.info("my redis expire-time config!");         var configuration = builder.cacheDefaults()                 .entryTtl(myRedisConfig.getDefaultExpireTime());          builder.cacheDefaults(configuration);          log.info("my redis expire-time cacheAndExpire has {} configs!", myRedisConfig.getCacheAndExpires().size());         for (CacheAndExpire cacheAndExpire : myRedisConfig.getCacheAndExpires()) {             var cacheConfig = builder.getCacheConfigurationFor(cacheAndExpire.getCacheName()).orElse(configuration);             builder.withCacheConfiguration(cacheAndExpire.getCacheName(), cacheConfig.entryTtl(cacheAndExpire.getExpireTime()));         }     } }  

将bean注入到Spring容器中

@EnableConfigurationProperties({MyRedisConfig.class}) public class RedisConfig {      @Bean     MyRedisCacheManagerBuilderCustomizer myRedisCacheManagerBuilderCustomizer(MyRedisConfig myRedisConfig) {         return new MyRedisCacheManagerBuilderCustomizer(myRedisConfig);     } } 

相关内容

热门资讯

第三方辅助挂!途游辅助软件网站... 第三方辅助挂!途游辅助软件网站!都是真的是有开挂辅助方法(有挂秘籍)-哔哩哔哩1、首先打开途游辅助软...
总结辅助挂!人海大厅挂什么好!... 总结辅助挂!人海大厅挂什么好!果然真的有开挂辅助插件(详细教程)-哔哩哔哩1、人海大厅挂什么好透视辅...
代打辅助挂!大菠萝789辅助器... 代打辅助挂!大菠萝789辅助器下载!总是是有开挂辅助神器(有挂技巧)-哔哩哔哩一、游戏安装教程牌型概...
现就发布提示!吉祥填大坑有插件... 现就发布提示!吉祥填大坑有插件麻!总是是有开挂辅助app(有挂秘诀)-哔哩哔哩运吉祥填大坑有插件麻辅...
现场直击!sohoo开挂辅助!... 现场直击!sohoo开挂辅助!都是存在有开挂辅助挂(有挂实锤)-哔哩哔哩1、透视辅助软件激活码多个强...
来临!手机游戏辅助脚本工具!本... 来临!手机游戏辅助脚本工具!本来是真的有开挂辅助软件(讲解有挂)-哔哩哔哩1、每一步都需要思考,不同...
此事迅速冲上热搜!熊猫辅助软件... 此事迅速冲上热搜!熊猫辅助软件!竟然确实有开挂辅助神器(有挂分析)-哔哩哔哩1、这是跨平台的轻量版有...
黑科技教程!可乐辅助!好像真的... 黑科技教程!可乐辅助!好像真的有开挂辅助方法(有挂工具)-哔哩哔哩1、游戏颠覆性的策略玩法,独创攻略...
据目击者称!丽水都莱辅助工具!... 据目击者称!丽水都莱辅助工具!真是存在有开挂辅助方法(有挂方针)-哔哩哔哩1、游戏颠覆性的策略玩法,...
今天下午!悠闲碰碰辅助!其实确... 今天下午!悠闲碰碰辅助!其实确实有开挂辅助神器(有挂辅助)-哔哩哔哩1、脚本辅助下载、免费透视脚本等...