Spring ap 中的 Guava 缓存作为基于时间的清理存储
Guava cache as time-based cleanup storage in Spring ap
我有一个 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甚至可以在定义的时间之前清理缓存在 expireAfterWrites
过去了( 甚至在此之前 运行 内存不足 )。
我如何配置 Guava Cache 以保留对象直到时间到期(考虑到它没有 运行 内存不足 )。也许我应该选择其他解决方案?
我不知道 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 提供程序,因此您可以使用它。也许那个版本没有展示您使用 Guava 的体验?如果是这样,预计会在 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. You can force that behaviour via the spring.cache.type
property。
我有一个 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甚至可以在定义的时间之前清理缓存在 expireAfterWrites
过去了( 甚至在此之前 运行 内存不足 )。
我如何配置 Guava Cache 以保留对象直到时间到期(考虑到它没有 运行 内存不足 )。也许我应该选择其他解决方案?
我不知道 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 提供程序,因此您可以使用它。也许那个版本没有展示您使用 Guava 的体验?如果是这样,预计会在 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. You can force that behaviour via the spring.cache.type
property。