1. 概述

在这篇文章中,我们将学习如何在使用Spring缓存抽象层时获取Caffeine缓存中的所有缓存键。

2. Spring 缓存

缓存是Spring框架的重要组成部分,自3.1版本以来就已成为Spring生态系统的一部分。它有一套定义明确且经过充分测试的接口。

让我们看看其中两个主要的:CacheManagerCache:

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上找到。