You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何查看Spring Boot默认缓存中的所有键值对?

解决Spring Boot默认缓存无法遍历所有键/内容的问题

当你使用Spring Boot默认的@EnableCaching(无外部缓存依赖)时,默认的ConcurrentMapCache并没有对外暴露缓存键的遍历能力,cache.getNativeCache()返回的ConcurrentHashMap也因Spring的封装无法直接访问键集合。以下是两种可行的解决方案:

方案一:自定义CacheManager与Cache实现(推荐)

通过扩展Spring的ConcurrentMapCacheManager和ConcurrentMapCache,让缓存实例暴露获取所有键的方法,这种方式符合Spring缓存抽象设计,版本兼容性更好。

  1. 自定义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();
    }
}
  1. 自定义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);
    }
}
  1. 注册自定义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();
    }
}
  1. 使用自定义缓存获取所有键与内容
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 16:06:29