spring-boot-2 redis-cache序列化配置注意点

spring-boot-2 redis-cache序列化配置注意点

spring-boot中@CacheXXX系列注解的使得缓存应用十分便利,但是其默认序列化格式为二进制,在配合redis使用时不能直观的观察缓存的数据,所以通常会手动将序列化方式改为json。

这样的序列化配置在网上很多,无非就是CachaManager的配置。
如:

@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
    RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
    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);

    RedisSerializationContext.SerializationPair<Object> pair = RedisSerializationContext.SerializationPair
            .fromSerializer(jackson2JsonRedisSerializer);
    RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
    redisCacheConfiguration .entryTtl(Duration.ofSeconds(300))
            .serializeValuesWith(pair);
    RedisCacheManager cacheManager = new RedisCacheManager(redisCacheWriter, redisCacheConfiguration());
    return cacheManager;
}

然后神奇的配置出现了:

 RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
 redisCacheConfiguration .entryTtl(Duration.ofSeconds(300))
         .serializeValuesWith(pair);

这样先获取redisCacheConfiguration在设置,就会发现redis中的类型为二进制,ttl也没有生效:
redis内容

然而只需要将配置的方式改为链式配置:

RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
        .entryTtl(Duration.ofSeconds(300))
        .serializeValuesWith(pair);

于是:
redis内容

分析原因

实际上是犯了经验主义的错误,习惯性的设置(配置)属性,而RedisCacheConfiguration的配置并不是在源对象上作设置的, 看源码:

public RedisCacheConfiguration serializeValuesWith(SerializationPair<?> valueSerializationPair) {
        Assert.notNull(valueSerializationPair, "ValueSerializationPair must not be null!");
        return new RedisCacheConfiguration(ttl, cacheNullValues, usePrefix, keyPrefix, keySerializationPair,
                valueSerializationPair, conversionService);
    }

没错,设置序列化后返回的是新的RedisCacheConfiguration。

所以……

知道原因后就没有什么好说的了,在此也只是记录,望自己以后引以为戒。

以下列出demo源码:
pom

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>RELEASE</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

config

@EnableCaching
@Configuration
public class RedisCacheConfig extends CachingConfigurerSupport {

    @Bean
    public RedisCacheConfiguration redisCacheConfiguration() {
        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);

        RedisSerializationContext.SerializationPair<Object> pair = RedisSerializationContext.SerializationPair
                .fromSerializer(jackson2JsonRedisSerializer);

        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(300))
                .serializeValuesWith(pair);

        return redisCacheConfiguration;
    }

    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
        //初始化一个RedisCacheWriter
        RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
        //初始化RedisCacheManager
        RedisCacheManager cacheManager = new RedisCacheManager(redisCacheWriter, redisCacheConfiguration());
        return cacheManager;
    }
}

service

@Service
public class RedisAnnotationCacheService {
    @CachePut(value = "CacheModel", key = "#version + '-' + #key + '-' + #value")
    public CacheModel save(String version, String key, String value) {
        return new CacheModel(version, key, value);
    }

}

test

public class RedisAnnotationCacheServiceTest extends RedisDemoApplicationTests {

    @Autowired
    RedisAnnotationCacheService service;

    @Test
    public void save() {
        service.save("v1.1.1", "AndroidInfo", "百度app");
    }

}
  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值