Spring纯编程式配置EhCache(JSR 107):重启后缓存为空的问题排查求助
看起来你遇到了纯编程式配置EhCache(JSR 107)重启后磁盘缓存丢失的问题,我来帮你排查代码中的关键问题并给出修复方案:
核心问题分析
你的代码已经配置了磁盘持久化目录,但存在3个关键缺失/错误,导致重启后缓存无法加载:
缓存未启用本地重启可恢复的持久化策略
虽然你在全局配置了DefaultPersistenceConfiguration,且磁盘资源池设置了persistent=true,但每个缓存的CacheConfiguration没有显式指定重启可恢复的持久化策略,EhCache默认不会自动加载磁盘缓存。CacheManager的URI参数传递错误
你将持久化目录的URI作为第一个参数传入provider.getCacheManager(),这会混淆CacheManager的实例标识与持久化路径。正确的做法是使用EhCache的默认URI或自定义唯一标识,持久化路径已经通过DefaultPersistenceConfiguration指定。缺少序列化保障
若WebServiceErgebnis类未实现Serializable/Externalizable接口,或未配置EhCache自定义序列化器,磁盘缓存的对象无法被反序列化,重启后自然为空。
修复后的完整配置代码
@Configuration @EnableCaching public class CacheConfig { public static final String CACHE_DAILY_EH = "cacheDailyEH"; @Value("${ehcache.directory}") private String ehcacheDirectory; @Bean @Primary public CacheManager ehCacheManager() { // 1. 配置资源池:开启磁盘持久化 ResourcePools resourcePools = ResourcePoolsBuilder.newResourcePoolsBuilder() // .heap(2000, EntryUnit.ENTRIES) // 按需启用堆内存 .disk(10, MemoryUnit.GB, true) // 第三个参数true=开启磁盘持久化 .build(); // 2. 配置单个缓存:显式启用LOCALRESTARTABLE持久化策略 CacheConfiguration<String, WebServiceErgebnis> cacheConfiguration = CacheConfigurationBuilder .newCacheConfigurationBuilder(String.class, WebServiceErgebnis.class, resourcePools) // 关键:指定重启可恢复的持久化策略 .persistence(PersistenceConfigurationBuilder.newPersistenceConfiguration() .strategy(Strategy.LOCALRESTARTABLE)) .build(); Map<String, CacheConfiguration<?, ?>> caches = new HashMap<>(); caches.put(CACHE_DAILY_EH, cacheConfiguration); // 3. 获取EhCache提供器 EhcacheCachingProvider provider = (EhcacheCachingProvider) Caching .getCachingProvider("org.ehcache.jsr107.EhcacheCachingProvider"); // 4. 全局配置:指定持久化目录 org.ehcache.config.Configuration configuration = new DefaultConfiguration( caches, provider.getDefaultClassLoader(), new DefaultPersistenceConfiguration(new File(ehcacheDirectory)) ); // 5. 获取CacheManager:使用默认URI,避免路径混淆 javax.cache.CacheManager cacheManager = provider.getCacheManager( provider.getDefaultURI(), // 使用EhCache默认的CacheManager标识URI configuration ); // 6. 包装为Spring的JCacheCacheManager JCacheCacheManager jCacheManager = new JCacheCacheManager(cacheManager); return jCacheManager; } }
额外注意事项
序列化要求
确保WebServiceErgebnis类实现Serializable接口,否则磁盘缓存的对象无法被反序列化:public class WebServiceErgebnis implements Serializable { // 类成员与方法 }如果无法修改类实现序列化,可以配置EhCache的自定义序列化器,在
CacheConfigurationBuilder中添加:.withKeySerializer(...) // 自定义键序列化器 .withValueSerializer(...) // 自定义值序列化器持久化目录权限
确保应用程序对ehcacheDirectory目录有读写权限,否则EhCache无法写入/读取磁盘缓存文件。CacheManager的生命周期管理
建议在Spring上下文关闭时正确关闭CacheManager,避免缓存数据损坏:@PreDestroy public void closeCacheManager() { if (jCacheManager != null) { jCacheManager.getCacheManager().close(); } }
内容来源于stack exchange

