1. 概述
在这篇文章中,我们将学习如何在使用Spring缓存抽象层时获取Caffeine缓存中的所有缓存键。
2. Spring 缓存
缓存是Spring框架的重要组成部分,自3.1版本以来就已成为Spring生态系统的一部分。它有一套定义明确且经过充分测试的接口。
让我们看看其中两个主要的:CacheManager
和Cache:
:
interface CacheManager {
Cache getCache(String name);
Collection<String> getCacheNames();
}
public interface Cache {
String getName();
Object getNativeCache();
ValueWrapper get(Object key);
<T> T get(Object key, @Nullable Class<T> type);
<T> T get(Object key, Callable<T> valueLoader);
void put(Object key, @Nullable Object value);
ValueWrapper putIfAbsent(Object key, @Nullable Object value);
void evict(Object key);
void clear();
}
如图所示,CacheManager
只是一个包装器,用于注册应用程序中可用的缓存区域。而Cache
对象则是区域内的一组键值对。
然而,它们都没有提供列出所有可用键的方法。
3. 配置
在我们探索访问所有可用键的方法之前,先定义我们的测试应用使用的CaffeineCacheManager
:
@Configuration
@EnableCaching
public class AllKeysConfig {
@Bean
CacheManager cacheManager() {
return new CaffeineCacheManager();
}
}
接下来,创建一个每次调用都会填充缓存的慢速服务:
public class SlowServiceWithCache {
@CachePut(cacheNames = "slowServiceCache", key = "#name")
public String save(String name, String details) {
return details;
}
}
有了缓存管理器和服务后,我们就可以准备在slowServiceCache
区域中查找键了。
4. 访问所有缓存键
正如我们已经学到的,CacheManager
并没有提供访问所有可用键的方法。Cache
接口也没有。
因此,我们需要利用我们在应用程序中定义的实际缓存实现的知识。 我们需要首先注入CacheManager
:
@Autowired
CacheManager cacheManager;
然后,进行一些简单的类型转换以访问原始的Caffeine Cache:
:
CaffeineCacheManager caffeineCacheManager = (CaffeineCacheManager) cacheManager;
CaffeineCache cache = (CaffeineCache) caffeineCacheManager.getCache("slowServiceCache");
Cache<Object, Object> caffeine = cache.getNativeCache();
接着,调用caffeine.asMap()
。由于它是一个映射,我们可以简单地通过caffeine.asMap().keySet()
来访问键:
@Test
public void givenCaffeineCacheCachingSlowCalls_whenCacheManagerProperlyCasted_thenAllKeysAreAccessible() {
slowServiceWithCache.save("first", "some-value-first");
slowServiceWithCache.save("second", "other-value-second");
Cache<Object, Object> caffeine = getNativeCaffeineCacheForSlowService();
assertThat(caffeine.asMap().keySet()).containsOnly("first", "second");
}
5. 总结
在这篇文章中,我们了解了如何从与Spring Cache一起使用的Caffeine缓存中访问所有可用的键。了解我们正在处理的实际缓存,只需要几个简单的类型转换操作即可访问所有键。
如往常一样,本文的代码可在GitHub上找到。