1. 程式人生 > >【springBoot】springBoot整合redis的key,value序列化的相關問題

【springBoot】springBoot整合redis的key,value序列化的相關問題

使用的是maven工程

springBoot整合redis預設使用的是註解,在官方文件中只需要2步;

1、在pom檔案中引入即可

 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-redis</artifactId>
</dependency>

2、編寫一個CacheService介面,使用redisCacheServiceImpl實現這個介面

     官網的原文是這樣的,也就是說,提供三個介面注入和你自己實現的其他實現類,預設是本地埠號為6379的redis

You can inject an auto-configured RedisConnectionFactory, StringRedisTemplate or vanilla RedisTemplate instance as you would any other Spring Bean.By default the instance will attempt to connect to a Redis server using localhost:6379:

我自己的redisCacheServiceImpl這樣寫的

複製程式碼
@Service
public class RedisCacheServiceImpl<K,V> implements
CacheService<K,V> { @Autowired RedisTemplate<K, V> redisTemplate; public void set(K key, V value) { redisTemplate.opsForValue().set(key, value); } }
複製程式碼

ok,這樣我們即可使用springBoot預設提供的redis服務,但是這樣有幾個問題,1序列化,我們set到redis伺服器中的key是這樣的

我們直接在cli中get key發現,在redisClent中發現是一堆看不懂的字元,解決這個問題就需要將key和value序列化,如果是xml配置的

我們直接注入官方給定的keySerializer,valueSerializer,hashKeySerializer即可,那麼使用註解的話我們需要自己編寫RedisCacheConfig配置類

快取主要有幾個要實現的類:

1、CacheManager快取管理器;

2、具體操作實現類;

3、CacheManager工廠類(這個可以使用配置檔案配置的進行注入,也可以通過編碼的方式進行實現);

4、快取key生產策略(當然Spring自帶生成策略,但是在Redis客戶端進行檢視的話是系列化的key,對於我們肉眼來說就是感覺是亂碼了,這裡我們先使用自帶的快取策略)。

複製程式碼
/**
 * 快取管理(註解用)
 * @author Administrator
 */
@Configuration
@EnableCaching//啟用快取的意思
public class CacheConfig extends CachingConfigurerSupport{
    
    /**
     * 自定義key. 這個可以不用
     * 此方法將會根據類名+方法名+所有引數的值生成唯一的一個key,即使@Cacheable中的value屬性一樣,key也會不一樣。
     */
   /* @Override
    public KeyGenerator keyGenerator() {
       System.out.println("RedisCacheConfig.keyGenerator()");
       returnnew KeyGenerator() {
           @Override
           public Object generate(Object o, Method method, Object... objects) {
              // This will generate a unique key of the class name, the method name
              //and all method parameters appended.
              StringBuilder sb = new StringBuilder();
              sb.append(o.getClass().getName());
              sb.append(method.getName());
              for (Object obj : objects) {
                  sb.append(obj.toString());
              }
              System.out.println("keyGenerator=" + sb.toString());
              returnsb.toString();
           }
       };
    }
    */
    
    @Bean
    public CacheManager cacheManager(RedisTemplate redisTemplate) {
        RedisCacheManager rcm = new RedisCacheManager(redisTemplate);
       /* //設定快取過期時間
        // rcm.setDefaultExpiration(60);//秒
        //設定value的過期時間
        Map<String,Long> map=new HashMap();
        map.put("test",60L);
        rcm.setExpires(map);*/
        return rcm;
    }
    /**
     * RedisTemplate配置
     * @param factory
     * @return
     */
    @Bean
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
        StringRedisTemplate template = new StringRedisTemplate(factory);
        //定義key序列化方式
        //RedisSerializer<String> redisSerializer = new StringRedisSerializer();//Long型別會出現異常資訊;需要我們上面的自定義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);
        
       // template.setKeySerializer(redisSerializer);
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }

}
複製程式碼

 當資料儲存到redis中時候key和value都是通過spring serializer進行序列化的,

RedisTemplate, spring預設會使用jdk序列化,如果使用jdk序列化,model模型必須實現Serializable且要有一個空的構造器,

StringRedisTemplate 預設是使用StringSerializer,同時springData還提供了其他的序列化方式,如下:

GenericToStringSerializer:使用Spring轉換服務進行序列化;
JacksonJsonRedisSerializer:使用Jackson 1,將物件序列化為JSON;
Jackson2JsonRedisSerializer:使用Jackson 2,將物件序列化為JSON;
JdkSerializationRedisSerializer:使用Java序列化;
OxmSerializer:使用Spring O/X對映的編排器和解排器(marshaler和unmarshaler)實現序列化,用於XML序列化;
StringRedisSerializer:序列化String型別的key和value。實際上是String和byte陣列之間的轉換

ok;基本解決了相關的序列化問題;程式碼有參考!