如何解决动态设置缓存 expireAfterWrite 属性 - Caffeine 和 Spring WebFlux
我正在使用咖啡因缓存来存储使用 webClient WebFlux 获得的授权令牌。我已将 expireAfterWrite 设置为 application.yml 文件中的硬编码值,如下所示:
spring:
cache:
cache-names: accesstokens
caffeine:
spec: expireAfterWrite=100m
使用带有 Spring WebFlux 的 WebClient 获取令牌,如下代码所示:
@Autowired
var cacheManager: CacheManager? = null
override fun getAuthToken(): Mono<Accesstoken> {
val map = LinkedMultiValueMap<String,String>()
map.add("client_id",clientId)
map.add("client_secret",clientSecret)
map.add("grant_type","client_credentials")
var cachedVersion = this.cacheManager?.getCache("accesstokens");
if (cachedVersion?.get("tokens") != null) {
val token = cachedVersion.get("tokens")
return Mono.just(token?.get() as Accesstoken)
} else {
return webClient.post()
.uri("/client-credentials/token")
.body(BodyInserters.fromFormData(map))
.retrieve()
.onStatus(HttpStatus::is5xxServerError) {
ClientLogger.logClientErrorResponse(it,errorResponse)
}
.onStatus(HttpStatus::is4xxClientError) {
ClientLogger.logClientErrorResponse(it,errorResponse)
}
.bodyToMono(Accesstoken::class.java)
.doOnNext { response ->
// Set here the expiration time of the cache based on
// response.expiresIn
this.cacheManager?.getCache("accesstokens")?.put("tokens",response) }
.log()
}
}
我在 .doOnNext() 方法中成功发出/返回数据后存储令牌,但我需要能够根据 expiresIn 属性设置过期时间或刷新缓存的硬编码过期时间响应对象的一部分,
.doOnNext { response ->
// Set here the expiration time of the cache based on
// response.expiresIn
this.cacheManager?.getCache("accesstokens")?.put("tokens",response)
}
任何想法将不胜感激。
解决方法
// Policy to set the lifetime based on when the entry was created
var expiresAfterCreate = new Expiry<String,AccessToken>() {
public long expireAfterCreate(String credentials,AccessToken token,long currentTime) {
Duration duration = token.expiresIn();
return token.toNanos();
}
public long expireAfterUpdate(String credentials,long currentTime,long currentDuration) {
return currentDuration;
}
public long expireAfterRead(String credentials,long currentDuration) {
return currentDuration;
}
});
// CompletableFuture-based cache
AsyncLoadingCache<String,AccessToken> cache = Caffeine.newBuilder()
.expireAfter(expiresAfterCreate)
.buildAsync((credentials,executor) -> {
Mono<AccessToken> token = retrieve(credentials);
return token.toFuture();
});
// Get from cache,loading if absent,and converts to Mono
Mono<AccessToken> getAuthToken() {
var token = cache.get(credentials);
return Mono.fromFuture(token);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。