首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >动态设置缓存expireAfterWrite属性- Caffeine和Spring WebFlux

动态设置缓存expireAfterWrite属性- Caffeine和Spring WebFlux
EN

Stack Overflow用户
提问于 2021-01-21 15:59:10
回答 1查看 909关注 0票数 0

我正在使用咖啡因缓存来存储使用webClient WebFlux获得的授权令牌。我在application.yml文件中将expireAfterWrite设置为硬编码值,如下所示:

代码语言:javascript
运行
复制
spring:
  cache:
    cache-names: accessTokens
    caffeine:
      spec: expireAfterWrite=100m

令牌是使用带有Spring WebFlux的WebClient获得的,如下代码所示:

代码语言:javascript
运行
复制
 @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属性设置过期时间或刷新缓存的硬编码过期时间。

代码语言:javascript
运行
复制
      .doOnNext { response ->    
                      // Set here the expiration time of the cache based on  
                      // response.expiresIn           
                      this.cacheManager?.getCache("accessTokens")?.put("tokens", response) 
                 }

任何想法都将不胜感激。

EN

回答 1

Stack Overflow用户

发布于 2021-01-22 02:36:45

代码语言:javascript
运行
复制
// 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, AccessToken token, 
      long currentTime, long currentDuration) {
    return currentDuration;
  }
  public long expireAfterRead(String credentials, AccessToken token,
      long currentTime, 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);
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65823211

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档