微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决动态设置缓存 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 举报,一经查实,本站将立刻删除。