Guava缓存作为Spring ap

时间:2015-12-28 08:26:30

标签: java caching spring-boot guava

我有一个Spring Boot / MVC应用程序,应该存储用户发送的一些简单POJO 15分钟。当此时间到期时,应从ConcurrentHashMap中删除此对象。起初ConcurrentHashMap是我想要实现此功能的东西,但后来我认为可能利用Guava的缓存是一个更好的选择,因为它有一个开箱即用的基于时间的驱逐。

我的服务实施

@CachePut(cacheNames = "teamConfigs", key = "#authAccessDto.accessToken")
@Override
public OAuthAccessDto saveConfig(OAuthAccessDto authAccessDto) {
    return authAccessDto;
}

@Override
@Cacheable(cacheNames = "teamConfigs")
public OAuthAccessDto getConfig(String accessToken) {
    // we assume that the cache is already populated
    return null;
}

如您所见,我们使用saveConfig保存数据,然后当我们需要检索数据时,我们会调用getConfig

Spring引导中的缓存配置如下(yml文件):

spring:
  cache:
    cache-names: teamConfigs
    guava:
      spec: expireAfterWrites=900s

然而,在阅读了Guava的缓存文档https://github.com/google/guava/wiki/CachesExplained之后,我发现Guava可以在 {{1}中定义的时间之前清除缓存过去(甚至在内存不足之前)。

如何配置Guava Cache以保持对象直到时间到期(认为它没有耗尽内存)。也许我应该选择其他解决方案?

1 个答案:

答案 0 :(得分:2)

我不了解Guava,但你可以使用任何符合JSR-107标准的提供商和一个看起来像这样的简单配置:

@Bean
public JCacheManagerCustomizer cacheManagerCustomizer() {
    return cm -> {
        cm.createCache("teamConfigs", new MutableConfiguration<>()
            .setExpiryPolicyFactory(CreatedExpiryPolicy     
                .factoryOf(new Duration(MINUTES, 15)));
    };
}

Caffeine(用Java8重写Guava)有一个JSR-107提供程序,所以你可以使用它。也许那个版本没有展示你对番石榴的体验?如果是这样,预计Spring Boot 1.4中会提供支持,但您现在可以尝试JSR-107支持。

如果您不想使用它,可以尝试expiringmap。它在Spring抽象中没有任何Cache实现,但由于它是Map,你可以很容易地将它包装起来,就像在我的头顶上一样:

@Bean
public Cache teamConfigsCache() {
    Map<Object, Object> map = ExpiringMap.builder()
        .expiration(15, TimeUnit.MINUTES)
        .build();
    return new ConcurrentMapCache("teamConfigs", map , true);
}

如果Spring Boot在配置中发现至少Cache个bean,it auto-creates a CacheManager implementation that wraps them。您可以通过the spring.cache.type property强制执行该行为。