为什么Spring @Cacheable没有将带注释的方法的结果类型传递给它的反序列化器?

问题描述 投票:3回答:1

这是Kotlin的示例代码。

@组态

@Bean("cacheManager1hour")
fun cacheManager1hour(@Qualifier("cacheConfig") cacheConfiguration: RedisCacheConfiguration, redisConnectionFactory: RedisConnectionFactory): CacheManager {
    cacheConfiguration.entryTtl(Duration.ofSeconds(60 * 60))
    return RedisCacheManager.builder(redisConnectionFactory)
            .cacheDefaults(cacheConfiguration)
            .build()
}

@Bean("cacheConfig")
fun cacheConfig(objectMapper:ObjectMapper): RedisCacheConfiguration {
    return RedisCacheConfiguration.defaultCacheConfig()
            .computePrefixWith { cacheName -> "yaya:$cacheName:" }
            .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(StringRedisSerializer()))
            .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(GenericJackson2JsonRedisSerializer()))

}

@RestController

@Cacheable(value = "book", key = "#root.methodName", cacheManager = "cacheManager1hour")
fun getBook(): Book {
    return Book()
}

class Book  {
    var asdasd:String? = "TEST"
    var expires_in = 123
}

GenericJackson2JsonRedisSerializer无法处理“kotlin类”,我们需要将“@class as property”添加到Redis缓存条目中。

无论如何,为什么我们需要@class? Spring上下文知道结果类型,为什么不通过它?我们有两个好处:

  1. 记忆力减少
  2. 串行器很容易,即objectMapper.readValue(str, T)

用于说明的带注释的Spring代码

// org.springframework.cache.interceptor.CacheAspectSupport
@Nullable
private Cache.ValueWrapper findInCaches(CacheOperationContext context, Object key) {
    for (Cache cache : context.getCaches()) {
        // --> maybe we can pass the context.method.returnType to doGet
        Cache.ValueWrapper wrapper = doGet(cache, key); 
        if (wrapper != null) {
            if (logger.isTraceEnabled()) {
                logger.trace("Cache entry for key '" + key + "' found in cache '" + 
        cache.getName() + "'");
            }
            return wrapper;
        }
    }
    return null;
}

// org.springframework.data.redis.cache.RedisCache
@Override
protected Object lookup(Object key) { 
    // -> there will get the deserialized type can pass to Jackson

    byte[] value = cacheWriter.get(name, createAndConvertCacheKey(key));

    if (value == null) {
        return null;
    }

    return deserializeCacheValue(value);
}
spring jackson spring-data-redis spring-cache
1个回答
0
投票

您的退货类型可能是:

  • 一些抽象的课
  • 一些界面

在这些情况下,返回类型几乎无法反序列化对象。编码实际的类总是有效的。

© www.soinside.com 2019 - 2024. All rights reserved.