You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何强制Spring Cache调用带返回类型参数的get方法?

让Spring Cache调用带类型参数的get(Object key, Class<T> type)方法

要解决Spring调用无类型get方法导致无法获取反序列化目标类型的问题,你需要调整Cache实现的逻辑,引导Spring优先调用带类型参数的get方法,具体步骤如下:

1. 修正无类型get方法的实现

Spring Cache切面在获取缓存时,会先尝试调用无参数类型的get(Object key)方法。如果该方法返回非null的ValueWrapper,Spring就会直接使用这个值,不会再调用带类型参数的重载方法。

因此,你需要修改SqlCache中的get(key: Any)方法,不要在该方法中硬编码反序列化类型(比如你当前写死的UserModel),而是让它返回null,迫使Spring转而调用带类型参数的get方法:

override fun get(key: Any): Cache.ValueWrapper? {
    // 无类型信息时无法正确反序列化,返回null让Spring调用带类型的方法
    return null
}

如果想明确禁止无类型get方法的调用(避免误用),也可以抛出异常:

override fun get(key: Any): Cache.ValueWrapper? {
    throw UnsupportedOperationException("该缓存需要类型信息才能反序列化,请使用带类型参数的get方法")
}

2. 确保带类型参数的get方法正确处理反序列化

你的get(key: Any, type: Class<T>?)方法已经实现了基于传入类型的反序列化逻辑,只需确保type参数不为空即可(Spring在调用该方法时,会自动传入目标方法的返回类型,比如UserModel::class.java):

override fun <T : Any?> get(key: Any, type: Class<T>?): T? {
    requireNotNull(type) { "反序列化需要指定目标类型" }
    val cache = cacheRepository.find(name = name, key = key.toString()) ?: return null
    return isoObjectMapper.readValue(cache.value, type)
}

3. 修正put方法的序列化逻辑

确保存储到数据库的是JSON字符串,而不是对象本身(避免cacheRepository处理序列化时出现不一致):

override fun put(key: Any, value: Any?) {
    val jsonValue = value?.let { isoObjectMapper.writeValueAsString(it) }
    cacheRepository.put(
        name = name,
        key = key.toString(),
        value = jsonValue,
        expiration = expiration,
    )
}

原理说明

当你使用@Cacheable注解时,Spring Cache切面会解析目标方法的返回类型(比如getUser方法的UserModel)。如果无类型get方法返回null,Spring会自动调用带类型参数的get(key, requiredType)方法,将目标方法的返回类型传入,这样你就能在缓存实现中基于该类型完成JSON反序列化。

内容的提问来源于stack exchange,提问作者Oreste Viron

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 17:50:24