SpringBoot怎么自定义Redis实现缓存序列化(redis,springboot,开发技术)

时间:2024-05-08 01:19:44 作者 : 石家庄SEO 分类 : 开发技术
  • TAG :

1、自定义RedisTemplate

1.1、Redis API默认序列化机制

基于API的Redis缓存实现是使用RedisTemplate模板进行数据缓存操作的,这里打开RedisTemplate类,查看该类的源码信息

publicclassRedisTemplate<K,V>extendsRedisAccessorimplementsRedisOperations<K,V>,BeanClassLoaderAware{//声明了key、value的各种序列化方式,初始值为空@NullableprivateRedisSerializerkeySerializer=null;@NullableprivateRedisSerializervalueSerializer=null;@NullableprivateRedisSerializerhashKeySerializer=null;@NullableprivateRedisSerializerhashValueSerializer=null;...//进行默认序列化方式设置,设置为JDK序列化方式publicvoidafterPropertiesSet(){super.afterPropertiesSet();booleandefaultUsed=false;if(this.defaultSerializer==null){this.defaultSerializer=newJdkSerializationRedisSerializer(this.classLoader!=null?this.classLoader:this.getClass().getClassLoader());}...}...}

从上述RedisTemplate核心源码可以看出,在RedisTemplate内部声明了缓存数据key、value的各种序列化方式,且初始值都为空;在afterPropertiesSet()方法中,判断如果默认序列化参数defaultSerializer为空,将数据的默认序列化方式设置为JdkSerializationRedisSerializer

根据上述源码信息的分析,可以得到以下两个重要的结论:

(1)使用RedisTemplate进行Redis数据缓存操作时,内部默认使用的是JdkSerializationRedisSerializer序列化方式,所以进行数据缓存的实体类必须实现JDK自带的序列化接口(例如Serializable);

(2)使用RedisTemplate进行Redis数据缓存操作时,如果自定义了缓存序列化方式defaultSerializer,那么将使用自定义的序列化方式。

另外,在RedisTemplate类源码中,看到的缓存数据key、value的各种序列化类型都是RedisSerializer。进入RedisSerializer源码查看RedisSerializer支持的序列化方式(进入该类后,使用Ctrl+Alt+左键单击类名查看)

SpringBoot怎么自定义Redis实现缓存序列化

可以看出,RedisSerializer是一个Redis序列化接口,默认有6个实现类,这6个实现类代表了6种不同的数据序列化方式。其中,JdkSerializationRedisSerializer是JDK自带的,也是RedisTemplate内部默认使用的数据序列化方式,开发者可以根据需要选择其他支持的序列化方式(例如JSON方式)

1.2、自定义RedisTemplate序列化机制

在项目中引入Redis依赖后,Spring Boot提供的RedisAutoConfiguration自动配置会生效。打开RedisAutoConfiguration类,查看内部源码中关于RedisTemplate的定义方式

publicclassRedisAutoConfiguration{@Bean@ConditionalOnMissingBean(name={"redisTemplate"})publicRedisTemplate<Object,Object>redisTemplate(RedisConnectionFactoryredisConnectionFactory)throwsUnknownHostException{RedisTemplate<Object,Object>template=newRedisTemplate();template.setConnectionFactory(redisConnectionFactory);returntemplate;}...}

从上述RedisAutoConfiguration核心源码中可以看出,在Redis自动配置类中,通过Redis连接工厂RedisConnectionFactory初始化了一个RedisTemplate;该类上方添加了@ConditionalOnMissingBean注解(顾名思义,当某个Bean不存在时生效),用来表明如果开发者自定义了一个名为redisTemplate的Bean,则该默认初始化的RedisTemplate不会生效。

如果想要使用自定义序列化方式的RedisTemplate进行数据缓存操作,可以参考上述核心代码创建一个名为redisTemplate的Bean组件,并在该组件中设置对应的序列化方式即可

接下来,在项目中创建名为com.lagou.config的包,在该包下创建一个Redis自定义配置类RedisConfig,并按照上述思路自定义名为redisTemplate的Bean组件

@ConfigurationpublicclassRedisConfig{//自定义RedisTemplate@BeanpublicRedisTemplate<Object,Object>redisTemplate(RedisConnectionFactoryredisConnectionFactory){RedisTemplate<Object,Object>template=newRedisTemplate<>();template.setConnectionFactory(redisConnectionFactory);//创建一个JSON格式序列化对象,对缓存数据的key和value进行转换Jackson2JsonRedisSerializerjackson2JsonRedisSerializer=newJackson2JsonRedisSerializer(Object.class);//解决查询缓存转换异常的问题ObjectMapperom=newObjectMapper();om.setVisibility(PropertyAccessor.ALL,JsonAutoDetect.Visibility.ANY);om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(om);//设置RedisTemplate模板api序列化方式为jsontemplate.setDefaultSerializer(jackson2JsonRedisSerializer);returntemplate;}}

通过@Configuration注解定义了一个RedisConfig配置类,并使用@Bean注解注入了一个默认名称为方法名的redisTemplate组件(注意,该Bean组件名称必须是redisTemplate)。在定义的Bean组件中,自定义了一个RedisTemplate,使用自定义的Jackson2JsonRedisSerializer数据序列化方式;在定制序列化方式中,定义了一个ObjectMapper用于进行数据转换设置

1.3、效果测试

SpringBoot怎么自定义Redis实现缓存序列化

可以看出,执行findById()方法正确查询出用户评论信息Comment,重复进行同样的查询操作,数据库只执行了一次SQL语句,这说明定制的Redis缓存生效。

使用Redis客户端可视化管理工具Redis Desktop Manager查看缓存数据 :

SpringBoot怎么自定义Redis实现缓存序列化

执行findById()方法查询出用户评论信息Comment正确存储到了Redis缓存库中,且缓存到Redis服务的数据已经使用了JSON格式存储展示,查看和管理也非常方便,说明自定义的Redis API模板工具RedisTemplate生效

2、自定义RedisCacheManager

刚刚针对基于 API方式的RedisTemplate进行了自定义序列化方式的改进,从而实现了JSON序列化方式缓存数据,但是这种自定义的RedisTemplate对于基于注解的Redis缓存来说,是没有作用的。

接下来,针对基于注解的Redis缓存机制和自定义序列化方式进行讲解

2.1、Redis注解默认序列化机制

打开Spring Boot整合Redis组件提供的缓存自动配置类RedisCacheConfiguration(org.springframework.boot.autoconfigure.cache包下的),查看该类的源码信息,其核心代码如下

@ConfigurationclassRedisCacheConfiguration{@BeanpublicRedisCacheManagercacheManager(RedisConnectionFactoryredisConnectionFactory,ResourceLoaderresourceLoader){RedisCacheManagerBuilderbuilder=RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(this.determineConfiguration(resourceLoader.getClassLoader()));List<String>cacheNames=this.cacheProperties.getCacheNames();if(!cacheNames.isEmpty()){builder.initialCacheNames(newLinkedHashSet(cacheNames));}return(RedisCacheManager)this.customizerInvoker.customize(builder.build());}privateorg.springframework.data.redis.cache.RedisCacheConfigurationdetermineConfiguration(ClassLoaderclassLoader){if(this.redisCacheConfiguration!=null){returnthis.redisCacheConfiguration;}else{RedisredisProperties=this.cacheProperties.getRedis();org.springframework.data.redis.cache.RedisCacheConfigurationconfig=org.springframework.data.redis.cache.RedisCacheConfiguration.defaultCacheConfig();config=config.serializeValuesWith(SerializationPair.fromSerializer(newJdkSerializationRedisSerializer(classLoader)));...returnconfig;}}}

从上述核心源码中可以看出,同RedisTemplate核心源码类似,RedisCacheConfiguration内部同样通过Redis连接工厂RedisConnectionFactory定义了一个缓存管理器RedisCacheManager;同时定制RedisCacheManager时,也默认使用了JdkSerializationRedisSerializer序列化方式。

如果想要使用自定义序列化方式的RedisCacheManager进行数据缓存操作,可以参考上述核心代码创建一个名为cacheManager的Bean组件,并在该组件中设置对应的序列化方式即可

注意,在Spring Boot 2.X版本中,RedisCacheManager是单独进行构建的。因此,在SpringBoot 2.X版本中,对RedisTemplate进行自定义序列化机制构建后,仍然无法对RedisCacheManager内部默认序列化机制进行覆盖(这也就解释了基 于注解的Redis缓存实现仍然会使用JDK默认序列化机制的原因),想要基于注解的Redis缓存实现也使用自定义序列化机制,需要自定义RedisCacheManager

2.2、自定义RedisCacheManager

在项目的Redis配置类RedisConfig中,按照上一步分析的定制方法自定义名为cacheManager的Bean组件

@BeanpublicRedisCacheManagercacheManager(RedisConnectionFactoryredisConnectionFactory){//分别创建String和JSON格式序列化对象,对缓存数据key和value进行转换RedisSerializer<String>strSerializer=newStringRedisSerializer();Jackson2JsonRedisSerializerjacksonSerial=newJackson2JsonRedisSerializer(Object.class);//解决查询缓存转换异常的问题ObjectMapperom=newObjectMapper();om.setVisibility(PropertyAccessor.ALL,JsonAutoDetect.Visibility.ANY);//om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL,JsonTypeInfo.As.PROPERTY);//上面注释过时代码的替代方法jacksonSerial.setObjectMapper(om);//定制缓存数据序列化方式及时效RedisCacheConfigurationconfig=RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofDays(1))//设置缓存数据的时效(设置为了1天).serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(strSerializer))//对当前对象的key使用strSerializer这个序列化对象,进行转换.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jacksonSerial))//对value使用jacksonSerial这个序列化对象,进行转换.disableCachingNullValues();RedisCacheManagercacheManager=RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(config).build();returncacheManager;}

上述代码中,在RedisConfig配置类中使用@Bean注解注入了一个默认名称为方法名的cacheManager组件。在定义的Bean组件中,通过RedisCacheConfiguration对缓存数据的key和value分别进行了序列化方式的定制,其中缓存数据的key定制为StringRedisSerializer(即String格式),而value定制为了Jackson2JsonRedisSerializer(即JSON格式),同时还使用entryTtl(Duration.ofDays(1))方法将缓存数据有效期设置为1天

完成基于注解的Redis缓存管理器RedisCacheManager定制后,可以对该缓存管理器的效果进行测试(使用自定义序列化机制的RedisCacheManager测试时,实体类可以不用实现序列化接口)

 </div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
本文:SpringBoot怎么自定义Redis实现缓存序列化的详细内容,希望对您有所帮助,信息来源于网络。
上一篇:Spring boot Thymeleaf怎么配置国际化页面下一篇:

12 人围观 / 0 条评论 ↓快速评论↓

(必须)

(必须,保密)

阿狸1 阿狸2 阿狸3 阿狸4 阿狸5 阿狸6 阿狸7 阿狸8 阿狸9 阿狸10 阿狸11 阿狸12 阿狸13 阿狸14 阿狸15 阿狸16 阿狸17 阿狸18