<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
剛剛完成了Spring Boot整合Redis進行了資料的快取管理,但快取管理的實體類資料使用的是JDK序列化方式,不便於使用視覺化管理工具進行檢視和管理。
接下來分別針對基於註解的Redis快取實現和基於API的Redis快取實現中的資料序列化機制進行介紹,並自定義JSON格式的資料序列化方式進行資料快取管理
基於API的Redis快取實現是使用RedisTemplate模板進行資料快取操作的,這裡開啟RedisTemplate類,檢視該類的原始碼資訊
public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperations<K, V>, BeanClassLoaderAware { // 宣告了key、value的各種序列化方式,初始值為空 @Nullable private RedisSerializer keySerializer = null; @Nullable private RedisSerializer valueSerializer = null; @Nullable private RedisSerializer hashKeySerializer = null; @Nullable private RedisSerializer hashValueSerializer = null; ... // 進行預設序列化方式設定,設定為JDK序列化方式 public void afterPropertiesSet() { super.afterPropertiesSet(); boolean defaultUsed = false; if (this.defaultSerializer == null) { this.defaultSerializer = new JdkSerializationRedisSerializer( 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+左鍵單擊類名檢視)
可以看出,RedisSerializer是一個Redis序列化介面,預設有6個實現類,這6個實現類代表了6種不同的資料序列化方式。其中,JdkSerializationRedisSerializer是JDK自帶的,也是RedisTemplate內部預設使用的資料序列化方式,開發者可以根據需要選擇其他支援的序列化方式(例如JSON方式)
在專案中引入Redis依賴後,Spring Boot提供的RedisAutoConfiguration自動設定會生效。開啟RedisAutoConfiguration類,檢視內部原始碼中關於RedisTemplate的定義方式
public class RedisAutoConfiguration { @Bean @ConditionalOnMissingBean( name = {"redisTemplate"} ) public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException { RedisTemplate<Object, Object> template = new RedisTemplate(); template.setConnectionFactory(redisConnectionFactory); return template; } ... }
從上述RedisAutoConfiguration核心原始碼中可以看出,在Redis自動設定類中,通過Redis連線工廠RedisConnectionFactory初始化了一個RedisTemplate;該類上方新增了@ConditionalOnMissingBean註解(顧名思義,當某個Bean不存在時生效),用來表明如果開發者自定義了一個名為redisTemplate的Bean,則該預設初始化的RedisTemplate不會生效。
如果想要使用自定義序列化方式的RedisTemplate進行資料快取操作,可以參考上述核心程式碼建立一個名為redisTemplate的Bean元件,並在該元件中設定對應的序列化方式即可
接下來,在專案中建立名為com.lagou.config的包,在該包下建立一個Redis自定義設定類RedisConfig,並按照上述思路自定義名為redisTemplate的Bean元件
@Configuration public class RedisConfig { // 自定義RedisTemplate @Bean public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<Object, Object> template = new RedisTemplate<>(); template.setConnectionFactory(redisConnectionFactory); // 建立一個JSON格式序列化物件,對快取資料的key和value進行轉換 Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); // 解決查詢快取轉換異常的問題 ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); // 設定RedisTemplate模板api序列化方式為json template.setDefaultSerializer(jackson2JsonRedisSerializer); return template; } }
通過@Configuration註解定義了一個RedisConfig設定類,並使用@Bean註解注入了一個預設名稱為方法名的redisTemplate元件(注意,該Bean元件名稱必須是redisTemplate)。在定義的Bean元件中,自定義了一個RedisTemplate,使用自定義的Jackson2JsonRedisSerializer資料序列化方式;在客製化序列化方式中,定義了一個ObjectMapper用於進行資料轉換設定
可以看出,執行findById()方法正確查詢出使用者評論資訊Comment,重複進行同樣的查詢操作,資料庫只執行了一次SQL語句,這說明客製化的Redis快取生效。
使用Redis使用者端視覺化管理工具Redis Desktop Manager檢視快取資料 :
執行findById()方法查詢出使用者評論資訊Comment正確儲存到了Redis快取庫中,且快取到Redis服務的資料已經使用了JSON格式儲存展示,檢視和管理也非常方便,說明自定義的Redis API模板工具RedisTemplate生效
剛剛針對基於 API方式的RedisTemplate進行了自定義序列化方式的改進,從而實現了JSON序列化方式快取資料,但是這種自定義的RedisTemplate對於基於註解的Redis快取來說,是沒有作用的。
接下來,針對基於註解的Redis快取機制和自定義序列化方式進行講解
開啟Spring Boot整合Redis元件提供的快取自動設定類RedisCacheConfiguration(org.springframework.boot.autoconfigure.cache包下的),檢視該類的原始碼資訊,其核心程式碼如下
@Configuration class RedisCacheConfiguration { @Bean public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory, ResourceLoader resourceLoader) { RedisCacheManagerBuilder builder = RedisCacheManager .builder(redisConnectionFactory) .cacheDefaults(this.determineConfiguration(resourceLoader.getClassLoader())); List<String> cacheNames = this.cacheProperties.getCacheNames(); if (!cacheNames.isEmpty()) { builder.initialCacheNames(new LinkedHashSet(cacheNames)); } return (RedisCacheManager) this.customizerInvoker.customize(builder.build()); } private org.springframework.data.redis.cache.RedisCacheConfiguration determineConfiguration(ClassLoader classLoader) { if (this.redisCacheConfiguration != null) { return this.redisCacheConfiguration; } else { Redis redisProperties = this.cacheProperties.getRedis(); org.springframework.data.redis.cache.RedisCacheConfiguration config = org.springframework.data.redis.cache.RedisCacheConfiguration.defaultCacheConfig(); config = config.serializeValuesWith(SerializationPair.fromSerializer( new JdkSerializationRedisSerializer(classLoader))); ... return config; } } }
從上述核心原始碼中可以看出,同RedisTemplate核心原始碼類似,RedisCacheConfiguration內部同樣通過Redis連線工廠RedisConnectionFactory定義了一個快取管理器RedisCacheManager;同時客製化RedisCacheManager時,也預設使用了JdkSerializationRedisSerializer序列化方式。
如果想要使用自定義序列化方式的RedisCacheManager進行資料快取操作,可以參考上述核心程式碼建立一個名為cacheManager的Bean元件,並在該元件中設定對應的序列化方式即可
注意,在Spring Boot 2.X版本中,RedisCacheManager是單獨進行構建的。因此,在SpringBoot 2.X版本中,對RedisTemplate進行自定義序列化機制構建後,仍然無法對RedisCacheManager內部預設序列化機制進行覆蓋(這也就解釋了基 於註解的Redis快取實現仍然會使用JDK預設序列化機制的原因),想要基於註解的Redis快取實現也使用自定義序列化機制,需要自定義RedisCacheManager
在專案的Redis設定類RedisConfig中,按照上一步分析的客製化方法自定義名為cacheManager的Bean元件
@Bean public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) { // 分別建立String和JSON格式序列化物件,對快取資料key和value進行轉換 RedisSerializer<String> strSerializer = new StringRedisSerializer(); Jackson2JsonRedisSerializer jacksonSerial = new Jackson2JsonRedisSerializer(Object.class); // 解決查詢快取轉換異常的問題 ObjectMapper om = new ObjectMapper(); 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); // 客製化快取資料序列化方式及時效 RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig() .entryTtl(Duration.ofDays(1)) // 設定快取資料的時效(設定為了1天) .serializeKeysWith(RedisSerializationContext.SerializationPair .fromSerializer(strSerializer)) // 對當前物件的key使用strSerializer這個序列化物件,進行轉換 .serializeValuesWith(RedisSerializationContext.SerializationPair .fromSerializer(jacksonSerial)) // 對value使用jacksonSerial這個序列化物件,進行轉換 .disableCachingNullValues(); RedisCacheManager cacheManager = RedisCacheManager .builder(redisConnectionFactory).cacheDefaults(config).build(); return cacheManager; }
上述程式碼中,在RedisConfig設定類中使用@Bean註解注入了一個預設名稱為方法名的cacheManager元件。在定義的Bean元件中,通過RedisCacheConfiguration對快取資料的key和value分別進行了序列化方式的客製化,其中快取資料的key客製化為StringRedisSerializer(即String格式),而value客製化為了Jackson2JsonRedisSerializer(即JSON格式),同時還使用entryTtl(Duration.ofDays(1))方法將快取資料有效期設定為1天
完成基於註解的Redis快取管理器RedisCacheManager客製化後,可以對該快取管理器的效果進行測試(使用自定義序列化機制的RedisCacheManager測試時,實體類可以不用實現序列化介面)
到此這篇關於SpringBoot自定義Redis實現快取序列化詳解的文章就介紹到這了,更多相關SpringBoot 快取序列化內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45