Spring Data Cache + Redis:如何避免将类名存储在序列化的 JSON 中,从而浪费大量空间?

fzy*_*cjy 5 java spring redis spring-data spring-cache

我正在使用 Spring Data Cache,并使用 Redis 作为缓存管理器。配置如下:

    return RedisCacheManager.builder(redisConnectionFactory)
        .cacheDefaults(
            RedisCacheConfiguration.defaultCacheConfig()
                .serializeKeysWith(SerializationPair.fromSerializer(RedisSerializer.string()))
                .serializeValuesWith(SerializationPair.fromSerializer(RedisSerializer.json()))
        )
        .build()
Run Code Online (Sandbox Code Playgroud)

让我们想象一个使用 spring 数据缓存的非常简单的例子:

@Cacheable(...)
MyPOJO compute() { ... }
Run Code Online (Sandbox Code Playgroud)

然而,RedisSerializer.json()确实是一个GenericJackson2JsonRedisSerializer。因此,恕我直言,它将存储诸如{"hello":"world","@class":"com.my.name.some.package.MyPOJO"}. 这@class: ...部分相当长,浪费了 Redis 中宝贵的内存。此外,恕我直言,Spring Data Cache 应该足够聪明,能够意识到值类型确实是MyPOJO,所以它不需要存储它"@class"

因此我的问题是:如何避免在 Spring Data Cache + Redis CacheManager 中将类名存储在序列化 JSON 中,这会浪费大量空间?

感谢您的任何建议!

小智 2

您是否研究过 GenericJackson2JsonRedisSerializer 的实现?看起来默认的对象映射器被配置为使用 Jackson 的多态类型功能。但还有一个选项可以传递自定义 ObjectMapper,如下所示:

SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer(objectMapper))
Run Code Online (Sandbox Code Playgroud)

您可以配置和传递自定义 Jacksons 对象映射器(带或不带类型信息)。有多种方法可以配置类型信息的存储方式(如果您确实需要):https://github.com/FasterXML/jackson-docs/wiki/JacksonPolymorphicDeserialization

在早期版本中,Spring 没有配置类型信息,如下所示:如何使用 GenericJackson2JsonRedisSerializer看起来这在更新的版本中已更改。但是,仍然可以选择根据需要配置序列化器。