spring-boot - Spring Webflux 和 @Cacheable - 缓存 Mono/Flux 类型结果的正确方法

标签 spring-boot spring-cache spring-webflux

我正在学习 Spring WebFlux,在编写示例应用程序的过程中,我发现了一个与 Reactive 类型(Mono/Flux)结合 Spring Cache 相关的问题。

考虑以下代码片段(在 Kotlin 中):

@Repository
interface TaskRepository : ReactiveMongoRepository<Task, String>

@Service
class TaskService(val taskRepository: TaskRepository) {

    @Cacheable("tasks")
    fun get(id: String): Mono<Task> = taskRepository.findById(id)
}

这是有效且安全的缓存方法调用返回 Mono 或 Flux 的方式吗?也许还有其他一些原则可以做到这一点?

以下代码与 SimpleCacheResolver 一起工作,但默认情况下,Redis 会失败,因为 Mono 不可序列化。为了使它们工作,例如需要使用 Kryo 序列化器。

最佳答案

黑客方式

暂时没有@Cacheable的流畅集成与 react 器 3。
但是,您可以通过添加 .cache() 绕过那个东西。运营商返回 Mono

@Repository
interface TaskRepository : ReactiveMongoRepository<Task, String>

@Service
class TaskService(val taskRepository: TaskRepository) {

    @Cacheable("tasks")
    fun get(id: String): Mono<Task> = taskRepository.findById(id).cache()
}

那个黑客 taskRepository 返回的缓存和共享数据。反过来,spring cacheable 将缓存返回的引用 Mono然后,将返回该引用。换句话说,它是一个保存缓存的单声道缓存:)。

react 堆插件方式

有一个addition到 Reactor 3,它允许与现代内存缓存(如 caffeine)流畅集成, jcache等。使用该技术,您将能够轻松缓存数据:
@Repository
interface TaskRepository : ReactiveMongoRepository<Task, String>

@Service
class TaskService(val taskRepository: TaskRepository) {

    @Autowire
    CacheManager manager;


    fun get(id: String): Mono<Task> = CacheMono.lookup(reader(), id)
                                               .onCacheMissResume(() -> taskRepository.findById(id))
                                               .andWriteWith(writer());

    fun reader(): CacheMono.MonoCacheReader<String, Task> = key -> Mono.<Signal<Task>>justOrEmpty((Signal) manager.getCache("tasks").get(key).get())
    fun writer(): CacheMono.MonoCacheWriter<String, Task> = (key, value) -> Mono.fromRunnable(() -> manager.getCache("tasks").put(key, value));
} 

Note: Reactor addons caching own abstraction which is Signal<T>, so, do not worry about that and following that convention

关于spring-boot - Spring Webflux 和 @Cacheable - 缓存 Mono/Flux 类型结果的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48156424/

相关文章:

java - Spring Boot Jasper 报告空白 PDF

java - 基于 Spring 的单个 ehcache 管理器,用于多模块项目中的多个 ehcache.xml 文件

java.lang.NoClassDefFoundError : net/sf/ehcache/concurrent/ReadWriteLockSync

java - 如何在没有方法参数的方法上使用 @cacheable 注释的键

java - 具有异步支持的 Spring Mvc 与 Spring WebFlux

java - 在运行时更改 Spring bean 实现

java - 从静态上下文调用 @Autowired 存储库

java - 如何将接受 Class<T> 并生成 T 的工厂方法集成到 Spring 中

java - Spring Webflux webclient 出现问题,尝试发送 post 请求时没有任何反应

java - 如何使用 spring webflux 上传和读取文本文件?