最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot自定義Redis實現緩存序列化詳解

 更新時間:2022年07月16日 08:55:58   作者:悠然予夏  
Spring提供了一個RedisTemplate來進行對Redis的操作,但是RedisTemplate默認配置的是使用Java本機序列化。如果要對對象操作,就不是那么的方便。所以本文為大家介紹了另一種SpringBoot結合Redis實現序列化的方法,需要的可以參考一下

剛剛完成了Spring Boot整合Redis進行了數據的緩存管理,但緩存管理的實體類數據使用的是JDK序列化方式,不便于使用可視化管理工具進行查看和管理。

接下來分別針對基于注解的Redis緩存實現和基于API的Redis緩存實現中的數據序列化機制進行介紹,并自定義JSON格式的數據序列化方式進行數據緩存管理

1、自定義RedisTemplate

1.1、Redis API默認序列化機制

基于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內部默認使用的數據序列化方式,開發(fā)者可以根據需要選擇其他支持的序列化方式(例如JSON方式)

1.2、自定義RedisTemplate序列化機制

在項目中引入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不存在時生效),用來表明如果開發(fā)者自定義了一個名為redisTemplate的Bean,則該默認初始化的RedisTemplate不會生效。

如果想要使用自定義序列化方式的RedisTemplate進行數據緩存操作,可以參考上述核心代碼創(chuàng)建一個名為redisTemplate的Bean組件,并在該組件中設置對應的序列化方式即可

接下來,在項目中創(chuàng)建名為com.lagou.config的包,在該包下創(chuàng)建一個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);
        // 創(chuàng)建一個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用于進行數據轉換設置

1.3、效果測試

可以看出,執(zhí)行findById()方法正確查詢出用戶評論信息Comment,重復進行同樣的查詢操作,數據庫只執(zhí)行了一次SQL語句,這說明定制的Redis緩存生效。

使用Redis客戶端可視化管理工具Redis Desktop Manager查看緩存數據 :

執(zhí)行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包下的),查看該類的源碼信息,其核心代碼如下

@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進行數據緩存操作,可以參考上述核心代碼創(chuàng)建一個名為cacheManager的Bean組件,并在該組件中設置對應的序列化方式即可

注意,在Spring Boot 2.X版本中,RedisCacheManager是單獨進行構建的。因此,在SpringBoot 2.X版本中,對RedisTemplate進行自定義序列化機制構建后,仍然無法對RedisCacheManager內部默認序列化機制進行覆蓋(這也就解釋了基 于注解的Redis緩存實現仍然會使用JDK默認序列化機制的原因),想要基于注解的Redis緩存實現也使用自定義序列化機制,需要自定義RedisCacheManager

2.2、自定義RedisCacheManager

在項目的Redis配置類RedisConfig中,按照上一步分析的定制方法自定義名為cacheManager的Bean組件

    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        // 分別創(chuàng)建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 緩存序列化內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Java字符串無意識的遞歸過程解析

    Java字符串無意識的遞歸過程解析

    這篇文章主要介紹了Java字符串無意識的遞歸過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-09-09
  • Java編程實現多線程TCP服務器完整實例

    Java編程實現多線程TCP服務器完整實例

    這篇文章主要介紹了Java編程實現多線程TCP服務器完整實例,具有一定借鑒價值,需要的朋友可以參考下
    2018-01-01
  • 深入剖析構建JSON字符串的三種方式(推薦)

    深入剖析構建JSON字符串的三種方式(推薦)

    下面小編就為大家?guī)硪黄钊肫饰鰳嫿↗SON字符串的三種方式(推薦)。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • 解決@Transaction注解導致動態(tài)切換更改數據庫失效問題

    解決@Transaction注解導致動態(tài)切換更改數據庫失效問題

    這篇文章主要介紹了解決@Transaction注解導致動態(tài)切換更改數據庫失效問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Java中spring boot validation自定義注解使用方式

    Java中spring boot validation自定義注解使用方式

    這篇文章主要介紹了Java中spring boot validation自定義注解使用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • Java實現FTP批量大文件上傳下載篇2

    Java實現FTP批量大文件上傳下載篇2

    這篇文章主要為大家詳細介紹了Java實現FTP批量大文件上傳下載的強化篇,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-08-08
  • Java之如何獲取泛型參數

    Java之如何獲取泛型參數

    在Java開發(fā)中,獲取泛型參數一般有兩種方法:第一種是通過JDK自帶的API,主要利用反射機制來獲取類的泛型信息;第二種方法是借助Spring框架提供的GenericTypeResolver工具類,這種方式更加簡便,這兩種方法都能有效地幫助開發(fā)者在運行時獲取到泛型參數
    2024-09-09
  • SpringBoot實現設置動態(tài)定時任務的方法詳解

    SpringBoot實現設置動態(tài)定時任務的方法詳解

    這篇文章主要介紹了SpringBoot實現設置動態(tài)定時任務的方法詳解,SpringBoot是一個快速開發(fā)的Java框架,而動態(tài)定時任務是指可以在運行時動態(tài)添加、修改和刪除定時任務的功能,需要的朋友可以參考下
    2023-10-10
  • 詳解SpringBoot基礎之banner玩法解析

    詳解SpringBoot基礎之banner玩法解析

    SpringBoot項目啟動時會在控制臺打印一個默認的啟動圖案,這個圖案就是我們要講的banner,這篇文章主要介紹了SpringBoot基礎之banner玩法解析,感興趣的小伙伴們可以參考一下
    2019-04-04
  • Spring Cloud Gateway 攔截響應問題分析(數據截斷問題)

    Spring Cloud Gateway 攔截響應問題分析(數據截斷問題)

    這篇文章主要介紹了Spring Cloud Gateway 攔截響應問題分析(數據截斷問題),本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-01-01

最新評論

六枝特区| 贵南县| 台中县| 江北区| 高碑店市| 黔西县| 四子王旗| 南丹县| 罗甸县| 驻马店市| 惠州市| 巴东县| 桂林市| 信阳市| 乌拉特前旗| 南涧| 会东县| 凤山县| 苍南县| 阜城县| 叙永县| 静乐县| 美姑县| 江西省| 开远市| 赣榆县| 合山市| 库伦旗| 衡南县| 温泉县| 应城市| 班玛县| 彰武县| 罗山县| 汕尾市| 昌都县| 化德县| 福清市| 无极县| 阳高县| 五大连池市|