在 Spring Boot 应用程序中从缓存中获取期间使用 @AutoValue 注释反序列化类

Posted

技术标签:

【中文标题】在 Spring Boot 应用程序中从缓存中获取期间使用 @AutoValue 注释反序列化类【英文标题】:Deserialize class with @AutoValue annotation during getting from cache in SpringBoot application 【发布时间】:2020-11-16 19:33:07 【问题描述】:

我创建了一个带有com.google.auto.value.AutoValue 注释的值类:

@AutoValue
@JsonDeserialize(builder = AutoValue_Company.Builder.class)
public abstract class Company 

public static Builder newBuilder() 
    return new AutoValue_Company.Builder();


@JsonProperty("id")
public abstract long id();

@JsonProperty("description")
public abstract String description();

@JsonProperty("websiteUrl")
public abstract String websiteUrl();

@AutoValue.Builder
public interface Builder 
    @JsonProperty("id")
    Builder id(long id);

    @JsonProperty("description")
    Builder description(String description);

    @JsonProperty("websiteUrl")
    Builder websiteUrl(String url);

    Company build();


从服务接收此类实例,并将结果缓存在 Redis 中:

@Cacheable(value = "company")
public Company getValue(String id)

RedisCacheManager 的配置如下:

@Bean(name = "valueCacheManager")
public RedisCacheManager valueCacheManager(final RedisConnectionFactory connectionFactory) 
    final RedisCacheWriter redisCacheWriter = RedisCacheWriter.lockingRedisCacheWriter(connectionFactory);
    RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
            .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
    cacheConfiguration = cacheConfiguration.entryTtl(Duration.ofSeconds(100));
    return new RedisCacheManager(redisCacheWriter, cacheConfiguration);

因此与反序列化有关的问题:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class com.test.models.AutoValue_Company and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)

【问题讨论】:

【参考方案1】:

通过将序列化程序GenericJackson2JsonRedisSerializer更改为Jackson2JsonRedisSerializer<>(Company.class)找到解决方案

所以缓存配置现在看起来像这样:

@Bean(name = "valueCacheManager")
public RedisCacheManager valueCacheManager(final RedisConnectionFactory connectionFactory) 
    final RedisCacheWriter redisCacheWriter = RedisCacheWriter.lockingRedisCacheWriter(connectionFactory);
    RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
             .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new Jackson2JsonRedisSerializer<>(Company.class)));
    cacheConfiguration = cacheConfiguration.entryTtl(Duration.ofSeconds(100));
    return new RedisCacheManager(redisCacheWriter, cacheConfiguration);

【讨论】:

【参考方案2】:

也许您应该使用 getters 约定命名您的方法,例如getId() 等?我认为this 是相关的。

【讨论】:

以上是关于在 Spring Boot 应用程序中从缓存中获取期间使用 @AutoValue 注释反序列化类的主要内容,如果未能解决你的问题,请参考以下文章

如何在spring boot中从同一个应用程序调用另一个api

如何在 Spring Boot 中从泛型参数(与任何类无关)中获取值

尝试在 Java Spring Boot 中从 H2 数据库中获取相关实体

在 Spring Boot 中从 jwt 获取附加属性

在spring boot应用程序中从自己的rest api调用另一个rest api

无法在 spring-boot 应用程序中从 Consul 读取配置