文章目錄
- RedisSerializer
- 為什么要使用
- 如何使用RedisSerializer
- 總結
RedisSerializer
為什么要使用
RedisTemplate
有默認的序列化器,但默認使用的
JdkSerializationRedisSerializer
存在一些問題:
- 序列化后的數據包含類信息等額外內容,導致存儲的數據體積較大
- 生成的是二進制數據,在 Redis 客戶端中查看時可讀性差
RedisTemplate
是操作 Redis 的主體,而 RedisSerializer
是 RedisTemplate
中負責數據格式轉換的關鍵組件。正確配置序列化器可以讓 Redis 存儲的數據更高效、更易讀、更具兼容性
首先看一下RedisTemplate
的部分源碼
這四個引用默認為空,當afterPropertiesSet方法進行判斷時,為空的話,默認創建一個jdk的序列化器,這就是后面我們會調用的類
現在我們使用這個對象的set方法,通過debug方式看看它怎么運行
當我們點擊set方法
會將傳入的key和value傳入rawKey和rawValue,當我們點入rawKey
這里的邏輯有點繞,可能大家會想,我明明沒有設置序列化器,為什么還是走else
其實不是
這里我們可以看到,如果我們不定義序列化器,他會把上面的afterPropertiesSet
方法初始化的JdkSerializationRedisSerializer
給keySerializer
,后續我們所調用的序列化器就有了默認的序列化器
小插曲:
大家知道為什么會調用afterPropertiesSet
方法嗎?
還是源碼
當一個 Bean 實現了 InitializingBean
接口后,Spring 容器在完成該 Bean 的所有屬性注入(即調用完所有 setter 方法)后,會自動調用接口中的 afterPropertiesSet()
方法。
書接上回,經過一系列的賦值和調用,這里會判斷是否已經自己定義序列化器,如果沒有,且我們自己將key給序列化了——不是自動的
比如我自己將"user:100"序列化了,這樣redis就能直接存儲原始的二進制,不需要再進行序列化轉換
雖然我們沒有設定序列化器但我們有默認的,且沒有手動將字符串序列化,所以我們走else
點擊serialize()
如果是debug的形式我們會進入這個類——熟悉嗎,上面初始化的類
點擊convert()
點擊serializeToByteArray()
這里我們可以看到通過ObjectOutputStream
類將java對象轉成字節
最后會在redis中以這樣的方式存儲
如何使用RedisSerializer
引入依賴
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId>
</dependency>
@Configuration
public class RedisConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {// 創建RedisTemplate對象RedisTemplate<String, Object> template = new RedisTemplate<>();// 設置連接工廠template.setConnectionFactory(connectionFactory);// 設置序列化工具GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer();// 設置key的序列化template.setKeySerializer(RedisSerializer.string());template.setHashKeySerializer(RedisSerializer.string());// 設置value的序列化template.setValueSerializer(serializer);template.setHashValueSerializer(serializer);// 返回return template;}}
這里實際上就是將我們之前提到的幾個引用為null的引用進行賦值,從而改變序列化器,改變reids中存儲的內容
@SpringBootTest
class SpringdataredisDemoApplicationTests {@Resourceprivate RedisTemplate redisTemplate;@Testvoid testString() {redisTemplate.opsForValue().set("name", "虎哥");// 從redis中獲取nameObject name = redisTemplate.opsForValue().get("name");System.out.println("name: " + name);}
}
總結
本篇博客介紹了有關RedisTemplate中的RedisSerializer,關于為什么要用,已經如何使用,如果有什么不正確或比較片面的地方,還望指正,謝謝大家!!!