SpringBoot使用@Cacheable出現(xiàn)預(yù)覽工具亂碼的解決方法
直接使用注解進(jìn)行緩存數(shù)據(jù),我們?cè)偈褂霉ぞ呷ヮA(yù)覽存儲(chǔ)的數(shù)據(jù)時(shí)發(fā)現(xiàn)是亂碼,這是由于默認(rèn)序列化的問題,默認(rèn)是使用JdkSerializationRedisSerializer,我們將其更改即可
解決辦法
我們重新定義一個(gè)org.springframework.data.redis.cache.RedisCacheConfiguration的Bean,并修改序列化器即可
/**
* 此類解決 @Cacheable 存入的緩存使用預(yù)覽工具時(shí)亂碼問題
*
* @author YinShangwen
* @since 2023/10/5 14:02
*/
@Configuration
public class RedisCacheConfig {
@Bean
public RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties) {
CacheProperties.Redis redisProperties = cacheProperties.getRedis();
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
// 工具預(yù)覽亂碼問題
config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericFastJsonRedisSerializer()));
if (redisProperties.getTimeToLive() != null) {
config = config.entryTtl(redisProperties.getTimeToLive());
}
if (redisProperties.getKeyPrefix() != null) {
config = config.prefixCacheNameWith(redisProperties.getKeyPrefix());
}
if (!redisProperties.isCacheNullValues()) {
config = config.disableCachingNullValues();
}
if (!redisProperties.isUseKeyPrefix()) {
config = config.disableKeyPrefix();
}
return config;
}
}??
注意:如果之前有@Cacheable方式存儲(chǔ)的緩存需要清理掉。否則會(huì)因?yàn)樾蛄谢?反序列化方式不一致而導(dǎo)致錯(cuò)誤
源碼導(dǎo)讀
RedisCache#put
找到 org.springframework.data.redis.cache.RedisCache#put 方法。這個(gè)方法就是最終存入的方法
/*
* (non-Javadoc)
* @see org.springframework.cache.Cache#put(java.lang.Object, java.lang.Object)
*/
@Override
public void put(Object key, @Nullable Object value) {
Object cacheValue = preProcessCacheValue(value);
if (!isAllowNullValues() && cacheValue == null) {
throw new IllegalArgumentException(String.format(
"Cache '%s' does not allow 'null' values. Avoid storing null via '@Cacheable(unless=\"#result == null\")' or configure RedisCache to allow 'null' via RedisCacheConfiguration.",
name));
}
cacheWriter.put(name, createAndConvertCacheKey(key), serializeCacheValue(cacheValue), cacheConfig.getTtl());
}serializeCacheValue
我們注意到serializeCacheValue(cacheValue)
private final RedisCacheConfiguration cacheConfig;
/**
* Serialize the value to cache.
*
* @param value must not be {@literal null}.
* @return never {@literal null}.
*/
protected byte[] serializeCacheValue(Object value) {
if (isAllowNullValues() && value instanceof NullValue) {
return BINARY_NULL_VALUE;
}
return ByteUtils.getBytes(cacheConfig.getValueSerializationPair().write(value));
}getValueSerializationPair
再看 cacheConfig.getValueSerializationPair() 是什么
private final SerializationPair<Object> valueSerializationPair;
/**
* @return never {@literal null}.
*/
public SerializationPair<Object> getValueSerializationPair() {
return valueSerializationPair;
}這個(gè)變量就是最終決定序列化的類了,如何設(shè)置呢?在RedisCacheConfiguration中有如下方法
/**
* Define the {@link SerializationPair} used for de-/serializing cache values.
*
* @param valueSerializationPair must not be {@literal null}.
* @return new {@link RedisCacheConfiguration}.
*/
public RedisCacheConfiguration serializeValuesWith(SerializationPair<?> valueSerializationPair) {
Assert.notNull(valueSerializationPair, "ValueSerializationPair must not be null!");
return new RedisCacheConfiguration(ttl, cacheNullValues, usePrefix, keyPrefix, keySerializationPair,
valueSerializationPair, conversionService);
}默認(rèn)的RedisCacheConfiguration如何被裝載
找到類org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration
注意:類名相同但包路徑不相同
org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration
org.springframework.data.redis.cache.RedisCacheConfiguration
class RedisCacheConfiguration {
...
private org.springframework.data.redis.cache.RedisCacheConfiguration createConfiguration(
CacheProperties cacheProperties, ClassLoader classLoader) {
Redis redisProperties = cacheProperties.getRedis();
org.springframework.data.redis.cache.RedisCacheConfiguration config = org.springframework.data.redis.cache.RedisCacheConfiguration
.defaultCacheConfig();
// 重點(diǎn)
config = config.serializeValuesWith(
SerializationPair.fromSerializer(new JdkSerializationRedisSerializer(classLoader)));
if (redisProperties.getTimeToLive() != null) {
config = config.entryTtl(redisProperties.getTimeToLive());
}
if (redisProperties.getKeyPrefix() != null) {
config = config.prefixCacheNameWith(redisProperties.getKeyPrefix());
}
if (!redisProperties.isCacheNullValues()) {
config = config.disableCachingNullValues();
}
if (!redisProperties.isUseKeyPrefix()) {
config = config.disableKeyPrefix();
}
return config;
}
}我們只看org.springframework.data.redis.cache.RedisCacheConfiguration是如何創(chuàng)建的所以省略了部分代碼
我們看到默認(rèn)使用的序列化器是 JdkSerializationRedisSerializer
以上就是SpringBoot使用@Cacheable出現(xiàn)預(yù)覽工具亂碼的解決方法的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot使用@Cacheable出現(xiàn)亂碼的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Mybatis-Plus之ID自動(dòng)增長的設(shè)置實(shí)現(xiàn)
本文主要介紹了Mybatis-Plus之ID自動(dòng)增長的設(shè)置實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07
java實(shí)現(xiàn)隊(duì)列數(shù)據(jù)結(jié)構(gòu)代碼詳解
這篇文章主要介紹了java實(shí)現(xiàn)隊(duì)列數(shù)據(jù)結(jié)構(gòu)代碼詳解,簡單介紹了隊(duì)列結(jié)構(gòu)以應(yīng)用場景,涉及詳細(xì)實(shí)現(xiàn)代碼,還是比較不錯(cuò)的,這里分享給大家,需要的朋友可以參考下。2017-11-11
java算法入門之有效的括號(hào)刪除有序數(shù)組中的重復(fù)項(xiàng)實(shí)現(xiàn)strStr
大家好,我是哪吒,一個(gè)熱愛編碼的Java工程師,本著"欲速則不達(dá),欲達(dá)則欲速"的學(xué)習(xí)態(tài)度,在程序猿這條不歸路上不斷成長,所謂成長,不過是用時(shí)間慢慢擦亮你的眼睛,少時(shí)看重的,年長后卻視若鴻毛,少時(shí)看輕的,年長后卻視若泰山,成長之路,亦是漸漸放下執(zhí)念,內(nèi)心歸于平靜的旅程2021-08-08
SpringMVC訪問靜態(tài)資源的三種方式小結(jié)
這篇文章主要介紹了SpringMVC訪問靜態(tài)資源的三種方式小結(jié),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-02-02
SpringAOP中@annotation與execution的深度示例對(duì)比分析
Spring AOP中@annotation通過注解標(biāo)記方法,適合定制化橫切邏輯;execution基于方法簽名匹配,用于通用功能增強(qiáng),兩者互補(bǔ),根據(jù)需求選擇,本文給大家介紹SpringAOP中@annotation與execution的深度示例對(duì)比分析,感興趣的朋友一起看看吧2025-08-08
Spring實(shí)現(xiàn)IoC和DI的方法詳解
IoC全稱Inversion of Control (控制反轉(zhuǎn)) ,這里的控制其實(shí)是控制權(quán)的意思,可以理解為對(duì)象的獲取權(quán)力和方式發(fā)生了發(fā)轉(zhuǎn),DI依賴注?是?個(gè)過程,是指IoC容器在創(chuàng)建Bean時(shí), 去提供運(yùn)?時(shí)所依賴的資源,?資源指的就是對(duì)象,本文介紹了Spring實(shí)現(xiàn)IoC和DI的方法2024-08-08

