springBoot集成redis的key,value序列化的相关问题

本文介绍如何在Spring Boot项目中集成Redis,并实现缓存管理。包括依赖添加、接口编写及序列化配置等步骤。

转载:https://www.cnblogs.com/gyjx2016/p/5893192.html

使用的是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数组之间的转换

转载于:https://www.cnblogs.com/wu-fm/p/8534440.html

在Spring Boot与Redis集成时,序列化方式的配置是关键的一部分,因为它决定了数据在Redis中如何存储读取。默认情况下,`RedisTemplate`使用`JdkSerializationRedisSerializer`进行序列化,但这通常不适合跨语言的场景,因为它生成的是二进制数据。因此,通常会根据需求更换为更通用的序列化方式,如`StringRedisSerializer`或`GenericJackson2JsonRedisSerializer`。 ### 配置键值的序列化方式 可以通过自定义 `RedisTemplate` 的 Bean 来设置键值的序列化器。以下是一个典型的配置示例: ```java @Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(factory); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); template.setHashKeySerializer(new StringRedisSerializer()); template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer()); template.afterPropertiesSet(); return template; } } ``` 上述配置中,`StringRedisSerializer`用于序列化键(key),而`GenericJackson2JsonRedisSerializer`用于序列化值(value)[^2]。这种方式可以确保键以字符串形式存储,值以JSON格式存储,便于调试跨语言交互。 ### 使用 `StringRedisSerializer` 的优势 当使用 `StringRedisSerializer` 时,键将直接以字符串形式存储,避免了不必要的编码问题,特别是在处理字符串类型的键时非常有用[^1]。如果未配置该序列化器,默认的 `JdkSerializationRedisSerializer` 会将键序列化为二进制格式,这在调试时不够友好。 ### 使用 `GenericJackson2JsonRedisSerializer` `GenericJackson2JsonRedisSerializer` 是 Spring 提供的一个 JSON 序列化器,它使用 Jackson 将对象转换为 JSON 字符串进行存储,并在反序列化时恢复为原始对象。这种方式适用于复杂对象的存储,并且保证了数据的可读性[^3]。 ### 配置连接池超时时间 除了序列化配置外,还可以在 `application.yml` 中配置 Redis 连接池超时时间,以优化性能: ```yaml spring: redis: host: 127.0.0.1 port: 6379 timeout: 10s lettuce: pool: min-idle: 0 max-idle: 8 max-active: 8 max-wait: -1ms ``` 该配置定义了 Redis 连接的基本参数,包括地址、端口、超时时间以及连接池的相关设置[^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值