自定義Redis緩存序列化機(jī)制

5.3?自定義Redis緩存序列化機(jī)制


?????????剛剛完成了Spring Boot整合Redis進(jìn)行了數(shù)據(jù)的緩存管理寥茫,但緩存管理的實體類數(shù)據(jù)使用的是JDK序列化方式,不便于使用可視化管理工具進(jìn)行查看和管理色乾。


![image-20191231142353290](./images/image-20191231142353290.png)


接下來分別針對基于注解的Redis緩存實現(xiàn)和基于API的Redis緩存實現(xiàn)中的數(shù)據(jù)序列化機(jī)制進(jìn)行介紹,并自定義JSON格式的數(shù)據(jù)序列化方式進(jìn)行數(shù)據(jù)緩存管理?


5.3.1?自定義RedisTemplate


1.Redis API默認(rèn)序列化機(jī)制


?????????基于API的Redis緩存實現(xiàn)是使用RedisTemplate模板進(jìn)行數(shù)據(jù)緩存操作的领突,這里打開RedisTemplate類暖璧,查看該類的源碼信息?


```java

public class RedisTemplate<K, V>

extends RedisAccessor

???????????????????????????????? implementsRedisOperations, BeanClassLoaderAware {

?????? //聲明了key、value的各種序列化方式君旦,初始值為空

???@Nullable

???private RedisSerializer keySerializer = null;

???@Nullable

???private RedisSerializer valueSerializer = null;

??? @Nullable

???private RedisSerializer hashKeySerializer = null;

???@Nullable

???private RedisSerializer hashValueSerializer = null;

?????? ...

?????? //進(jìn)行默認(rèn)序列化方式設(shè)置澎办,設(shè)置為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內(nèi)部聲明了緩存數(shù)據(jù)key、value的各種序列化方式局蚀,且初始值都為空悍汛;在afterPropertiesSet()方法中,判斷如果默認(rèn)序列化參數(shù)defaultSerializer為空至会,將數(shù)據(jù)的默認(rèn)序列化方式設(shè)置為JdkSerializationRedisSerializer?


??????? ??? 根據(jù)上述源碼信息的分析离咐,可以得到以下兩個重要的結(jié)論:


(1)使用RedisTemplate進(jìn)行Redis數(shù)據(jù)緩存操作時,內(nèi)部默認(rèn)使用的是JdkSerializationRedisSerializer序列化方式奉件,所以進(jìn)行數(shù)據(jù)緩存的實體類必須實現(xiàn)JDK自帶的序列化接口(例如Serializable)宵蛀;


(2)使用RedisTemplate進(jìn)行Redis數(shù)據(jù)緩存操作時,如果自定義了緩存序列化方式defaultSerializer县貌,那么將使用自定義的序列化方式术陶。


?????????另外,在RedisTemplate類源碼中煤痕,看到的緩存數(shù)據(jù)key梧宫、value的各種序列化類型都是RedisSerializer。進(jìn)入RedisSerializer源碼查看RedisSerializer支持的序列化方式(進(jìn)入該類后摆碉,使用Ctrl+Alt+左鍵單擊類名查看)?


![屏幕快照 2019-12-31 下午4.43.04](/Users/ericsun/Desktop/屏幕快照2019-12-31 下午4.43.04.png)


?????????可以看出塘匣,RedisSerializer是一個Redis序列化接口,默認(rèn)有6個實現(xiàn)類巷帝,這6個實現(xiàn)類代表了6種不同的數(shù)據(jù)序列化方式忌卤。其中,JdkSerializationRedisSerializer是JDK自帶的楞泼,也是RedisTemplate內(nèi)部默認(rèn)使用的數(shù)據(jù)序列化方式驰徊,開發(fā)者可以根據(jù)需要選擇其他支持的序列化方式(例如JSON方式)?




?2.自定義RedisTemplate序列化機(jī)制


?????????在項目中引入Redis依賴后,Spring

Boot提供的RedisAutoConfiguration自動配置會生效堕阔。打開RedisAutoConfiguration類棍厂,查看內(nèi)部源碼中關(guān)于RedisTemplate的定義方式?


```java

public class RedisAutoConfiguration {

???@Bean

???@ConditionalOnMissingBean(

???????name = {"redisTemplate"}

??? )

???public RedisTemplateredisTemplate(RedisConnectionFactory

?????? ????????????????????????????????redisConnectionFactory) throws UnknownHostException {

???????RedisTemplate template = new RedisTemplate();

???????template.setConnectionFactory(redisConnectionFactory);

???????return template;

??? }

?????? ...

}

```


從上述RedisAutoConfiguration核心源碼中可以看出,在Redis自動配置類中超陆,通過Redis連接工廠RedisConnectionFactory初始化了一個RedisTemplate牺弹;該類上方添加了@ConditionalOnMissingBean注解(顧名思義,當(dāng)某個Bean不存在時生效)侥猬,用來表明如果開發(fā)者自定義了一個名為redisTemplate的Bean例驹,則該默認(rèn)初始化的RedisTemplate不會生效。


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


?????????接下來,在項目中創(chuàng)建名為com.lagou.config的包瞧预,在該包下創(chuàng)建一個Redis自定義配置類RedisConfig屎债,并按照上述思路自定義名為redisTemplate的Bean組件?


```java

@Configuration

public class RedisConfig {


???@Bean

???public RedisTemplate redisTemplate(RedisConnectionFactory

??????????????????????????????????????????????????????????????redisConnectionFactory) {

???????RedisTemplate template = new RedisTemplate();

???????template.setConnectionFactory(redisConnectionFactory);

???????//使用JSON格式序列化對象仅政,對緩存數(shù)據(jù)key和value進(jìn)行轉(zhuǎn)換

???????Jackson2JsonRedisSerializer jacksonSeial = newJackson2JsonRedisSerializer(Object.class);


???????//解決查詢緩存轉(zhuǎn)換異常的問題

???????ObjectMapper om = new ObjectMapper();

???????om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);

???????om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

???????jacksonSeial.setObjectMapper(om);

???????//設(shè)置RedisTemplate模板API的序列化方式為JSON

???????template.setDefaultSerializer(jacksonSeial);

???????return template;

??? }

}

```


?????????通過@Configuration注解定義了一個RedisConfig配置類,并使用@Bean注解注入了一個默認(rèn)名稱為方法名的redisTemplate組件(注意盆驹,該Bean組件名稱必須是redisTemplate)圆丹。在定義的Bean組件中,自定義了一個RedisTemplate躯喇,使用自定義的Jackson2JsonRedisSerializer數(shù)據(jù)序列化方式辫封;在定制序列化方式中,定義了一個ObjectMapper用于進(jìn)行數(shù)據(jù)轉(zhuǎn)換設(shè)置?


????**3.效果測試**


?????????啟動項目廉丽,項目啟動成功后倦微,通過瀏覽器訪問“http://localhost:8080/api/findCommentById?id=3”查詢id為3的用戶評論信息,并重復(fù)刷新瀏覽器查看同一條數(shù)據(jù)信息?


![image-20191231170732322](./images/image-20191231170732322.png)


查看控制臺打印的SQL查詢語句


![image-20191231170819323](./images/image-20191231170819323.png)


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


?????????使用Redis客戶端可視化管理工具Redis

Desktop Manager查看緩存數(shù)據(jù) :


<img src="./images/image-20191231170942007.png"

alt="image-20191231170942007" style="zoom:67%;" />




?????????執(zhí)行findById()方法查詢出用戶評論信息Comment正確存儲到了Redis緩存庫中,且緩存到Redis服務(wù)的數(shù)據(jù)已經(jīng)使用了JSON格式存儲展示嘉裤,查看和管理也非常方便郑临,說明自定義的Redis API模板工具RedisTemplate生效?

剛學(xué)了拉勾教育的《Java工程師高薪訓(xùn)練營》,看到剛學(xué)到的點就回答了价脾。希望拉勾能給我推到想去的公司牧抵,目標(biāo):字節(jié)!侨把!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市妹孙,隨后出現(xiàn)的幾起案子秋柄,更是在濱河造成了極大的恐慌,老刑警劉巖蠢正,帶你破解...
    沈念sama閱讀 219,589評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件骇笔,死亡現(xiàn)場離奇詭異,居然都是意外死亡嚣崭,警方通過查閱死者的電腦和手機(jī)笨触,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評論 3 396
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來雹舀,“玉大人芦劣,你說我怎么就攤上這事∷涤埽” “怎么了虚吟?”我有些...
    開封第一講書人閱讀 165,933評論 0 356
  • 文/不壞的土叔 我叫張陵寸认,是天一觀的道長。 經(jīng)常有香客問我串慰,道長偏塞,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,976評論 1 295
  • 正文 為了忘掉前任邦鲫,我火速辦了婚禮灸叼,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘庆捺。我一直安慰自己怜姿,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,999評論 6 393
  • 文/花漫 我一把揭開白布疼燥。 她就那樣靜靜地躺著沧卢,像睡著了一般。 火紅的嫁衣襯著肌膚如雪醉者。 梳的紋絲不亂的頭發(fā)上但狭,一...
    開封第一講書人閱讀 51,775評論 1 307
  • 那天,我揣著相機(jī)與錄音撬即,去河邊找鬼立磁。 笑死,一個胖子當(dāng)著我的面吹牛剥槐,可吹牛的內(nèi)容都是我干的唱歧。 我是一名探鬼主播,決...
    沈念sama閱讀 40,474評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼粒竖,長吁一口氣:“原來是場噩夢啊……” “哼颅崩!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蕊苗,我...
    開封第一講書人閱讀 39,359評論 0 276
  • 序言:老撾萬榮一對情侶失蹤沿后,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后朽砰,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體尖滚,經(jīng)...
    沈念sama閱讀 45,854評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,007評論 3 338
  • 正文 我和宋清朗相戀三年瞧柔,在試婚紗的時候發(fā)現(xiàn)自己被綠了漆弄。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,146評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡造锅,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出备绽,到底是詐尸還是另有隱情,我是刑警寧澤宇驾,帶...
    沈念sama閱讀 35,826評論 5 346
  • 正文 年R本政府宣布他挎,位于F島的核電站筹淫,受9級特大地震影響损姜,放射性物質(zhì)發(fā)生泄漏摧阅。R本人自食惡果不足惜棒卷,卻給世界環(huán)境...
    茶點故事閱讀 41,484評論 3 331
  • 文/蒙蒙 一太颤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧做裙,春花似錦、人聲如沸拧廊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春皮假,著一層夾襖步出監(jiān)牢的瞬間钞翔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評論 1 272
  • 我被黑心中介騙來泰國打工席舍, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留布轿,地道東北人。 一個月前我還...
    沈念sama閱讀 48,420評論 3 373
  • 正文 我出身青樓来颤,卻偏偏與公主長得像汰扭,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子福铅,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,107評論 2 356