如何查看Spring Boot默认缓存中的所有键值对?
解决Spring Boot默认缓存无法遍历所有键/内容的问题
当你使用Spring Boot默认的@EnableCaching(无外部缓存依赖)时,默认的ConcurrentMapCache并没有对外暴露缓存键的遍历能力,cache.getNativeCache()返回的ConcurrentHashMap也因Spring的封装无法直接访问键集合。以下是两种可行的解决方案:
方案一:自定义CacheManager与Cache实现(推荐)
通过扩展Spring的ConcurrentMapCacheManager和ConcurrentMapCache,让缓存实例暴露获取所有键的方法,这种方式符合Spring缓存抽象设计,版本兼容性更好。
- 自定义ExposedConcurrentMapCache类
import org.springframework.cache.concurrent.ConcurrentMapCache; import java.util.Set; public class ExposedConcurrentMapCache extends ConcurrentMapCache { public ExposedConcurrentMapCache(String name) { super(name); } // 暴露获取所有缓存键的方法 public Set<Object> getKeys() { return getNativeCache().keySet(); } }
- 自定义ExposedConcurrentMapCacheManager类
import org.springframework.cache.concurrent.ConcurrentMapCacheManager; import org.springframework.cache.Cache; public class ExposedConcurrentMapCacheManager extends ConcurrentMapCacheManager { @Override protected Cache createCache(String name) { // 创建自定义的缓存实例 return new ExposedConcurrentMapCache(name); } }
- 注册自定义CacheManager到Spring容器
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.cache.annotation.EnableCaching; @Configuration @EnableCaching public class CacheConfig { @Bean public ExposedConcurrentMapCacheManager cacheManager() { return new ExposedConcurrentMapCacheManager(); } }
- 使用自定义缓存获取所有键与内容
import org.springframework.cache.Cache; import org.springframework.cache.CacheManager; import org.springframework.stereotype.Component; @Component public class CacheViewer { private final CacheManager cacheManager; public CacheViewer(CacheManager cacheManager) { this.cacheManager = cacheManager; } // 打印指定缓存的所有键值对 public void printAllCacheEntries(String cacheName) { Cache cache = cacheManager.getCache(cacheName); if (cache instanceof ExposedConcurrentMapCache exposedCache) { exposedCache.getKeys().forEach(key -> { Cache.ValueWrapper valueWrapper = exposedCache.get(key); System.out.printf("缓存键:%s,对应值:%s%n", key, valueWrapper != null ? valueWrapper.get() : "null"); }); } } }
方案二:反射获取缓存键(应急用,不推荐)
如果不想修改缓存配置,可以通过反射直接读取ConcurrentHashMap内部的存储结构,但这种方式依赖Spring的内部实现,版本升级后可能失效,仅适合临时调试使用。
import org.springframework.cache.Cache; import org.springframework.cache.CacheManager; import org.springframework.stereotype.Component; import java.lang.reflect.Field; import java.util.Map; import java.util.Set; @Component public class TempCacheViewer { private final CacheManager cacheManager; public TempCacheViewer(CacheManager cacheManager) { this.cacheManager = cacheManager; } // 反射获取指定缓存的所有键 public Set<Object> getCacheKeys(String cacheName) throws Exception { Cache cache = cacheManager.getCache(cacheName); if (cache == null) { return Set.of(); } Object nativeCache = cache.getNativeCache(); // 反射获取ConcurrentHashMap的内部存储map Field mapField = nativeCache.getClass().getDeclaredField("map"); mapField.setAccessible(true); Map<Object, Object> cacheMap = (Map<Object, Object>) mapField.get(nativeCache); return cacheMap.keySet(); } }
说明
Spring默认缓存的设计遵循通用缓存抽象,很多生产级缓存(如Redis、Caffeine)本身不支持高效遍历所有键,因此默认实现没有暴露该能力。如果后续需要切换到外部缓存,建议避免依赖遍历键的逻辑,改用其他方式(如维护键的集合到单独缓存)。
内容的提问来源于stack exchange,提问作者pvs nagarjun
相关产品推荐
相关产品推荐

