【问题标题】:spring boot cache not support kotlin?spring boot 缓存不支持kotlin?
【发布时间】:2017-07-24 10:33:25
【问题描述】:

我正在尝试用 kotlin 替换一些 java 代码。

比如jpa或者cache。

开始类是:

@EnableAsync
@EnableCaching
@EnableSwagger2
@SpringBootApplication
open class Application

fun main(args: Array<String>) {
    SpringApplication.run(Application::class.java)
}

简单的控制器:

@RestController
class CacheController {

    @Autowired
    private lateinit var cache: CacheService

    @PutMapping("{id}")
    fun save(@PathVariable id: Long) {
        cache.save(id)
    }
}

缓存服务:

@Component
@CacheConfig(cacheNames = arrayOf("longCacheManager"), cacheManager = "longCacheManager")
open class CacheService {

    @Cacheable(key = "#id")
    fun save(id: Long): Long {
        return id
    }
}

缓存管理器:

@Configuration
open class CacheConfig {

    @Autowired
    private lateinit var redisConnectionFactory: RedisConnectionFactory

    @Bean
    @Qualifier("longCacheManager")
    open fun longCacheManager(): CacheManager {
        val redisTemplate = StringRedisTemplate(redisConnectionFactory)
        redisTemplate.valueSerializer = GenericToStringSerializer(Long::class.java)
        val cacheManager = RedisCacheManager(redisTemplate)
        cacheManager.setUsePrefix(true)
        return cacheManager
    }
}

可以确认在CacheService的方法save中输入的id参数,但是执行完PutMethod后,redis里面什么都没有。

当我像这样用java编写cacheServie时,redis会保存我想要的。

Java 缓存服务是这样的:

@Component
@CacheConfig(cacheNames = "longCacheManager", cacheManager = "longCacheManager")
public class JavaCacheService {

    @Cacheable(key = "#id")
    public Long save(Long id) {
        return id;
    }
}

我也读过这样的文章: https://pathtogeek.com/spring-boot-caching-with-kotlin

我的 SpringBootVersion 是 1.5.3.RELEASE 而 kotlinVersion 是 1.1.3-2

【问题讨论】:

  • 如果没有@EnableCaching,这些注释几乎毫无用处。您链接到的文章中也很清楚地解释了这一点。
  • @EnableCaching 在包含 SpringApplication.run(Application.class); 的启动类中
  • 将其添加到您的问题中以确保完整性。
  • 为什么您的 Configuration/cacheManager 类是用 Java 编写的,而其他所有东西都是用 Kotlin 编写的?
  • @M.Deinum 已添加

标签: caching spring-boot redis kotlin


【解决方案1】:

谢谢大家,我已经通过打开缓存方法来修复它

@Component
@CacheConfig(cacheNames = arrayOf("longCacheManager"), cacheManager = "longCacheManager")
open class CacheService {

    @Cacheable(key = "#id.toString()")
    open fun save(id: Long): Long {
        return id
    }
}

Spring 使用 cglib 生成代理。

它必须强制继承类和方法。

但是 kotlin 默认是 final class 和没有关键字 open 的方法。

【讨论】:

  • 如果您使用 kotlin-spring Gradle 插件,它将在构建时使 Spring 注释成员 open 无需更改代码以使用框架:kotlinlang.org/docs/reference/…
  • 谢谢,然后我也看到了相应的文章。但是在单元测试(如mock)中仍然不行。如果有对应的单元测试用例
  • Mockito 2 现在支持模拟最终成员。见这里:hadihariri.com/2016/10/04/Mocking-Kotlin-With-Mockito 它现在也比博客文章中描述的要简单一些,因为您需要做的就是将此依赖项添加到测试范围:org.mockito:mockito-inline:2.8.47
  • 非常感谢您的回答,mockito-inline 解决了无法模拟最终会员的问题。
猜你喜欢
  • 2015-03-03
  • 2020-12-04
  • 2015-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-18
  • 2020-03-16
  • 2021-05-10
相关资源
最近更新 更多