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

我正在学习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不是Serializable.为了使它们工作,例如需要使用Kryo序列化器.

最佳答案
哈克方式

目前,@ Cacheable与Reactor 3没有流畅的集成.
但是,您可以通过向返回的Mono添加.cache()运算符来绕过该事物

@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数据返回的hack缓存和共享.反过来,spring cacheable将缓存返回Mono的引用,然后返回该引用.换句话说,它是一个保存缓存的单声道缓存:).

Reactor Addons Way

Reactor 3有一个addition,可以与现代内存缓存(如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类型缓存结果的正确方法 - 代码日志