自定義RedisTemplate
序列化源碼分析
- 在JAVA程序中看到中文是沒有問題的,但是在Redis客戶端工具,也就是命令行中看見是編碼的

- 繼續分析源碼
- 查看RedisTemplate.class
- 在RedisAutoConfiguration.class中點擊

- 在上面可以看到序列化支持的

- 往下稍微滑動一些可以看到,默認采用的是JDK的序列化,因為默認4種都是空的

- 但是我們一般都是采用JSON來做序列化的,這個時候就需要自己定義序列化了
默認序列化存在的問題
- 創建測試實體類,User

package co.flower.redis02springboot.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.springframework.stereotype.Component; @Data @Component @AllArgsConstructor @NoArgsConstructor public class User { private String name; private int age; } 測試存儲JSON /** * 測試默認序列化 */ @Test public void testSerial() throws JsonProcessingException { User user = new User("小姐姐", 18); // 使用jackson轉換為字符串,我也沒用過 String jsonUser = new ObjectMapper().writeValueAsString(user); redisTemplate.opsForValue().set("user",jsonUser); System.out.println(redisTemplate.opsForValue().get("user")); } 執行結果 {"name":"小姐姐","age":18} 測試存儲對象User /** * 測試默認序列化 */ @Test public void testSerial() throws JsonProcessingException { User user = new User("小姐姐", 18); // 使用jackson轉換為字符串,我也沒用過 // String jsonUser = new ObjectMapper().writeValueAsString(user); redisTemplate.opsForValue().set("user",user); System.out.println(redisTemplate.opsForValue().get("user")); } 執行結果 // org.springframework.data.redis.serializer.SerializationException:
Cannot serialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException:
Failed to serialize object using DefaultSerializer; nested exception is java.lang.IllegalArgumentException: DefaultSerializer requires
a Serializable payload but received an object of type [co.flower.redis02springboot.pojo.User] at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.serialize(JdkSerializationRedisSerializer.java:96)
- 提示不能序列化,因為沒有實現Serializable接口,所以不能被JDKSerialzationRedisSerializer序列化
- 為User實現Serializable接口

- 再次測試,執行成功
- 返回結果:User(name=小姐姐, age=18)
自定義RedisTemplate
- 在java下創建config包,里面創建RedisConfig.java

- 復制源碼中的代碼進行改動
- 自己設置序列化方式
- 設置方法
- 通過redisTemplate對象進行設置
- 比如:setKeySerializer

- 點擊入參

- 查看實現類,就知道有哪些能設置了

- 配置類代碼 RedisConfig.java
package co.flower.redis02springboot.config; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; @Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<String, Object> template = new RedisTemplate(); template.setConnectionFactory(redisConnectionFactory); // JSON序列化配置 不需要被,不需要知道具體參數含義 大概知道是做什么的就可以 這個就是采用JSON序列化對象 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); // String的序列化配置 StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); // 所有的Key通過String序列化 template.setKeySerializer(stringRedisSerializer); template.setHashKeySerializer(stringRedisSerializer); // 所有的value通過JSON序列化 template.setValueSerializer(jackson2JsonRedisSerializer); template.setHashValueSerializer(jackson2JsonRedisSerializer); // 調用剛才看的序列化源碼中默認的方法,重新設置序列化 template.afterPropertiesSet(); return template; } } 采用自定義配置之后,清空數據庫再次測試測試代碼如下 /** * 測試自定義序列化 */ @Test public void testSerial() throws JsonProcessingException { User user = new User("小姐姐", 18); // 使用jackson轉換為字符串,我也沒用過 // String jsonUser = new ObjectMapper().writeValueAsString(user); redisTemplate.getConnectionFactory().getConnection().flushDb();// 清空數據庫 redisTemplate.opsForValue().set("user",user); System.out.println(redisTemplate.opsForValue().get("user")); }
- 沒有問題,查詢數據庫,直接從客戶端查詢

- 也沒有問題,OK,nice,開發中如果使用的話,直接拷貝就可以用了!當然是配置類,但是一般開發中不直接在業務中引入redisTemplate,而是編寫一個RedisUtils工具類,來包裝一下默認的,因為使用起來比較麻煩~,我就不照着視屏巧了,好幾百行[捂臉],用的時候直接從公司拿,沒有的話百度一個!
問題AQF:
依賴報錯:
在依賴redis的時候不要指定泛型,不然會報錯
/** * 我居然直接就指定了泛型 RedisTemplate<String,Object>結果就直接報錯了,刪除泛型后成功 */ @Autowired private RedisTemplate redisTemplate;
作者:彼岸舞
時間:2021\05\05
內容關於:Redis
本文屬於作者原創,未經允許,禁止轉發
