chr*_*con 10 java spring spring-webflux
我需要缓存来自的数据ReactiveMongoRepository.数据大约每年更新两次,所以我不关心缓存是否到期.
由于我们不能使用带有通量的@Cacheable,我想找到一种直接,简单的方法来存储从Mongo到redis的数据,并使用该数据(如果存在),否则存储它并提供原始数据.
是否有比这更简单的方法
@GetMapping
public Flux<AvailableInspection> getAvailableInspectionsRedis() {
AtomicInteger ad = new AtomicInteger();
return availableInspectionReactiveRedisOperations.opsForZSet().range("availableInspections", Range.<Long>from(Range.Bound.inclusive(0L)).to(Range.Bound.inclusive(-1L)))
.switchIfEmpty(availableInspectionMongoRepository.findAll().map(e -> {
availableInspectionReactiveRedisOperations.opsForZSet().add("availableInspections", e, ad.getAndIncrement()).block();
return e;
}));
}
Run Code Online (Sandbox Code Playgroud)
我正在寻找的是一个允许我像@Cacheable注释那样缓存数据的选项.我正在寻找能够缓存任何通量的通用解决方案.
我怀疑是否存在针对该问题的现成解决方案。但是,您可以轻松构建自己的接口以获取通用的缓存对象并将其加载到缓存中:
public interface GetCachedOrLoad<T> {
Flux<T> getCachedOrLoad(String key, Flux<T> loader, Class<? extends T> clazz);
}
Run Code Online (Sandbox Code Playgroud)
每个需要此功能的类都将通过构造函数注入它,并按如下方式使用它:
public class PersistedObjectRepository {
private final GetCachedOrLoad<PersistedObject> getCachedOrLoad;
public PersistedObjectRepository(final GetCachedOrLoad<PersistedObject> getCachedOrLoad) {
this.getCachedOrLoad = getCachedOrLoad;
}
public Flux<PersistedObject> queryPersistedObject(final String key) {
return getCachedOrLoad.getCachedOrLoad(key, queryMongoDB(key), PersistedObject.class);
}
private Flux<PersistedObject> queryMongoDB(String key) {
// use reactivemongo api to retrieve Flux<PersistedObject>
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您需要创建一个实现对象GetCachedOrLoad<T>并将其用于依赖项注入。
public class RedisCache<T> implements GetCachedOrLoad<T> {
private final Function<String, Flux<String>> getFromCache;
private final BiConsumer<String, String> loadToCache;
private final Gson gson;
public RedisCache(Gson gson, RedisReactiveCommands<String, String> redisCommands) {
this.getFromCache = key -> redisCommands.lrange(key, 0, -1);
this.loadToCache = redisCommands::lpush;
this.gson = gson;
}
@Override
public Flux<T> getCachedOrLoad(final String key, Flux<T> loader, Class<? extends T> clazz) {
final Flux<T> cacheResults = getFromCache.apply(key)
.map(json -> gson.fromJson(json, clazz));
return cacheResults.switchIfEmpty(
loader.doOnNext(value -> loadToCache.accept(key, gson.toJson(value))));
}
}
Run Code Online (Sandbox Code Playgroud)
希望这足够通用:)。
PS。这不是生产就绪的实现,需要针对您自己的需求进行调整,例如添加异常处理,自定义json序列化等。
| 归档时间: |
|
| 查看次数: |
811 次 |
| 最近记录: |