在 Kotlin 中使用 Jackson2JsonRedisSerializer 的通用 RedisTemplate

Posted

技术标签:

【中文标题】在 Kotlin 中使用 Jackson2JsonRedisSerializer 的通用 RedisTemplate【英文标题】:Generic RedisTemplate using Jackson2JsonRedisSerializer in Kotlin 【发布时间】:2020-04-28 12:49:00 【问题描述】:

我的控制器使用 redis 模板从 redis 获取和设置数据

val redisTemplate: RedisTemplate<String, Game>

模板是使用 bean 注入的

@Bean
fun <T> redisTemplate(builder: RestTemplateBuilder): RedisTemplate<String, T> 
    val serializer = Jackson2JsonRedisSerializer(Game::class.java)
    serializer.setObjectMapper(objectMapper)

    val template = RedisTemplate<String, T>()
    template.setConnectionFactory(connectionFactory())
    template.setDefaultSerializer(serializer)
    return template

这可行,但是我必须明确说明要序列化的***类,因此返回的模板仅适用于 RedisTemplate&lt;String, Game&gt; 而不适用于 RedisTemplate&lt;String, T&gt;

我已尝试将序列化程序实例更改为以下内容,但无法编译。

val serializer = Jackson2JsonRedisSerializer(T::class.java)

我已尝试将其更改为以下

val serializer = Jackson2JsonRedisSerializer(Object::class.java)

这可以编译,但是从 redis 读取时出现异常

java.lang.ClassCastException: class java.util.LinkedHashMap cannot be cast to class com.noicesoftware.redis.model.Game (java.util.LinkedHashMap is in module java.base of loader 'bootstrap'; com.noicesoftware.redis.model.Game is in unnamed module of loader 'app')

我曾尝试使用 GenericJackson2JsonRedisSerializer,但我得到了上述行为和异常。

val serializer = GenericJackson2JsonRedisSerializer(objectMapper)

任何想法将不胜感激。完整代码可在此处获得; https://github.com/DangerousDarlow/springboot-redis

【问题讨论】:

【参考方案1】:

我还没有找到保持 bean 通用的解决方案。如果我使类型具体化,那么我还必须使函数内联,然后是私有的或最终的。这会导致运行时错误。我的解决方案是将通用代码移动到私有内联函数中,然后为我想要的每种模板类型声明一个 bean。没有我希望的那么整洁,但我想也不算太糟糕。

private inline fun <reified T> getRedisTemplate(): RedisTemplate<String, T> 
    val serializer = Jackson2JsonRedisSerializer(T::class.java)
    serializer.setObjectMapper(objectMapper)

    val template = RedisTemplate<String, T>()
    template.setConnectionFactory(connectionFactory())
    template.setDefaultSerializer(serializer)
    return template


@Bean
fun redisTemplate(): RedisTemplate<String, Game> = getRedisTemplate()

【讨论】:

以上是关于在 Kotlin 中使用 Jackson2JsonRedisSerializer 的通用 RedisTemplate的主要内容,如果未能解决你的问题,请参考以下文章

使用 Kotlin 提高生产力

如何在Kotlin中使用Gradle构建缓存?

如何在 Kotlin Multiplatform(纯 kotlin)中进行延迟

如何在 Kotlin 中使用 ViewModelProviders

如何在 kotlin 中使用片段

在 Java 中使用 Kotlin 库