[英]Spring Cache in a reactive application
I am using the Spring Cache default implementation(ConcurrentHashMap):我正在使用 Spring 缓存默认实现(ConcurrentHashMap):
@Bean
CacheManager cacheManager() {
ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager("mycache");
cacheManager.setAllowNullValues(false);
return cacheManager;
}
Reactor addons is used to get an item.反应堆插件用于获取项目。 On cache miss item is written to the cache:缓存未命中项写入缓存:
public Mono<T> get(ID key) {
return CacheMono.lookup(k -> findValue(k).map(Signal::next), key)
.onCacheMissResume(Mono.defer(valueRetriever(key)))
.andWriteWith((k, signal) -> Mono.fromRunnable(() -> {
if (!signal.isOnError()) {
writeValue(k, signal.get());
}
}));
}
private void writeValue(ID key, T value) {
if (value != null) {
cache.put(key, value);
}
}
Does cache.put(key, value);
cache.put(key, value);
considered a blocking call?被认为是阻塞电话? Should be published on a different Scheduler?应该在不同的调度器上发布吗?
Yes.是的。
If you have the opportunity, I would suggest you to use ReactiveRedisConnection with Lettuce instead.如果你有机会,我建议你改用 ReactiveRedisConnection 和Lettuce 。
You could for example setup your beans as follows:例如,您可以按如下方式设置您的 bean:
@Bean
public ReactiveRedisConnectionFactory reactiveRedisConnectionFactory() {
final RedisStandaloneConfiguration redisConfig
= new RedisStandaloneConfiguration(SpringBootApp.redisHost, SpringBootApp.redisPort);
redisConfig.setPassword(SpringBootApp.redisPassword);
redisConfig.setDatabase(0);
final LettuceConnectionFactory connFac = new LettuceConnectionFactory(redisConfig);
return connFac;
}
@Bean
public ReactiveRedisConnection reactiveRedisConnection(final ReactiveRedisConnectionFactory redisConnectionFactory) {
return redisConnectionFactory.getReactiveConnection();
}
@Bean
public ReactiveRedisOperations<String, Object> redisOperations(ReactiveRedisConnectionFactory factory) {
final JdkSerializationRedisSerializer serializer = new JdkSerializationRedisSerializer();
final RedisSerializationContext.RedisSerializationContextBuilder<String, Object> builder = RedisSerializationContext
.newSerializationContext(new StringRedisSerializer());
final RedisSerializationContext<String, Object> context = builder.value(serializer).build();
return new ReactiveRedisTemplate<>(factory, context);
}
Then you can use ReactiveRedisOperations
to store/retrieve your data from your cache non-blocking.然后,您可以使用ReactiveRedisOperations
从缓存非阻塞中存储/检索数据。 You could do something like:您可以执行以下操作:
Mono.just("my_cache_key::" + uniqueId)
.flatMap(key -> reactiveRedisOps.opsForValue().get(key)
.cast(MyObj.class)
.switchIfEmpty(
getMyObjNonBlocking()
.flatMap(myObj -> ops.opsForValue().set(key, myObj,
Duration.ofMinutes(ttl))
.thenReturn(myObj))
));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.