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

Spring纯编程式配置EhCache(JSR 107):重启后缓存为空的问题排查求助

Spring纯编程式配置EhCache(JSR 107):重启后缓存为空的问题排查求助

看起来你遇到了纯编程式配置EhCache(JSR 107)重启后磁盘缓存丢失的问题,我来帮你排查代码中的关键问题并给出修复方案:


核心问题分析

你的代码已经配置了磁盘持久化目录,但存在3个关键缺失/错误,导致重启后缓存无法加载:

  1. 缓存未启用本地重启可恢复的持久化策略
    虽然你在全局配置了DefaultPersistenceConfiguration,且磁盘资源池设置了persistent=true,但每个缓存的CacheConfiguration没有显式指定重启可恢复的持久化策略,EhCache默认不会自动加载磁盘缓存。

  2. CacheManager的URI参数传递错误
    你将持久化目录的URI作为第一个参数传入provider.getCacheManager(),这会混淆CacheManager的实例标识与持久化路径。正确的做法是使用EhCache的默认URI或自定义唯一标识,持久化路径已经通过DefaultPersistenceConfiguration指定。

  3. 缺少序列化保障
    若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;
    }
}

额外注意事项

  1. 序列化要求
    确保WebServiceErgebnis类实现Serializable接口,否则磁盘缓存的对象无法被反序列化:

    public class WebServiceErgebnis implements Serializable {
        // 类成员与方法
    }
    

    如果无法修改类实现序列化,可以配置EhCache的自定义序列化器,在CacheConfigurationBuilder中添加:

    .withKeySerializer(...) // 自定义键序列化器
    .withValueSerializer(...) // 自定义值序列化器
    
  2. 持久化目录权限
    确保应用程序对ehcacheDirectory目录有读写权限,否则EhCache无法写入/读取磁盘缓存文件。

  3. CacheManager的生命周期管理
    建议在Spring上下文关闭时正确关闭CacheManager,避免缓存数据损坏:

    @PreDestroy
    public void closeCacheManager() {
        if (jCacheManager != null) {
            jCacheManager.getCacheManager().close();
        }
    }
    

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 07:34:31