0

我正在使用咖啡因缓存来存储使用 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) 
                 }

任何想法将不胜感激。

4

1 回答 1

2
// 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);
}
于 2021-01-21T18:36:45.377 回答