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

SpringMVC 5.x迁移EhCache 3.x遇类型转换异常 求无XML配置方案

解决Spring 5 + EhCache 3.x的缓存配置问题(无XML方案)

你的ClassCastException问题根源很明确:你直接把EhCache 3原生的org.ehcache.CacheManager强转成了Spring的org.springframework.cache.CacheManager——这两个是完全不同的类型,Spring提供了专门的适配类EhCacheCacheManager来桥接两者,这是你需要补上的关键一步。

下面是针对Spring 5 + EhCache 3.x的完整无XML配置方案,完全满足你按不同过期时间、对象类型配置多缓存的需求:

1. 确保依赖正确

首先要引入必要的依赖(以Maven为例):

<dependencies>
    <!-- Spring Cache 核心依赖 -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>5.3.x.RELEASE</version> <!-- 对应你的Spring 5版本 -->
    </dependency>
    <!-- EhCache 3.x核心依赖 -->
    <dependency>
        <groupId>org.ehcache</groupId>
        <artifactId>ehcache</artifactId>
        <version>3.10.x</version> <!-- 使用最新稳定版即可 -->
    </dependency>
    <!-- Spring与EhCache 3的适配依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-cache</artifactId>
        <version>2.7.x.RELEASE</version> <!-- 适配Spring 5的版本,若不用Spring Boot可单独引入spring-cache-support -->
    </dependency>
</dependencies>

2. 完整的Java配置类

这里我们定义两个不同的缓存配置(你可以根据需求扩展更多):

import org.ehcache.config.CacheConfiguration;
import org.ehcache.config.builders.CacheConfigurationBuilder;
import org.ehcache.config.builders.ExpiryPolicyBuilder;
import org.ehcache.config.builders.ResourcePoolsBuilder;
import org.ehcache.core.EhcacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.time.Duration;

@EnableCaching
@Configuration
public class CacheConf {

    // 定义第一个缓存配置:比如properties缓存,过期1小时,堆内存最多存1000条
    private CacheConfiguration<Object, Object> getPropertiesCacheConfig() {
        return CacheConfigurationBuilder.newCacheConfigurationBuilder(
                        Object.class, Object.class,
                        ResourcePoolsBuilder.heap(1000)
                )
                .withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofHours(1)))
                .build();
    }

    // 定义第二个缓存配置:比如propertyTypes缓存,过期1天,堆内存最多存500条
    private CacheConfiguration<Object, Object> getPropertyTypesCacheConfig() {
        return CacheConfigurationBuilder.newCacheConfigurationBuilder(
                        Object.class, Object.class,
                        ResourcePoolsBuilder.heap(500)
                )
                .withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofDays(1)))
                .build();
    }

    // 创建EhCache 3原生的CacheManager
    @Bean
    public org.ehcache.CacheManager ehCacheManager() {
        return org.ehcache.config.builders.CacheManagerBuilder.newCacheManagerBuilder()
                .withCache("properties", getPropertiesCacheConfig())
                .withCache("propertyTypes", getPropertyTypesCacheConfig())
                // 可继续添加更多不同配置的缓存
                .build(true); // true表示立即初始化缓存管理器
    }

    // 用Spring的适配类包装原生EhCache Manager,提供给Spring Cache体系使用
    @Bean
    public org.springframework.cache.CacheManager cacheManager(org.ehcache.CacheManager ehCacheManager) {
        return new EhCacheCacheManager((EhcacheManager) ehCacheManager);
    }
}

3. 关键细节说明

  • 类型适配:通过EhCacheCacheManager将EhCache 3的原生管理器包装成Spring认可的CacheManager,彻底解决类型转换异常。
  • 多缓存定制:每个缓存可以通过独立的CacheConfiguration配置不同的过期时间、内存限制、存储介质(比如要用到堆外内存或磁盘存储,只需修改ResourcePoolsBuilder即可)。
  • 类型安全优化:如果你的缓存有明确的Key/Value类型,比如用String当Key、Property当Value,可以把Object.class替换成具体类型,获得编译期类型校验:
    CacheConfiguration<String, Property> getPropertiesCacheConfig() {
        return CacheConfigurationBuilder.newCacheConfigurationBuilder(
                        String.class, Property.class,
                        ResourcePoolsBuilder.heap(1000)
                )
                .withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofHours(1)))
                .build();
    }
    

4. 缓存使用示例

配置完成后,就可以用Spring的缓存注解正常使用了:

@Cacheable(value = "properties", key = "#propertyId")
public Property getProperty(String propertyId) {
    // 从数据库/其他数据源获取数据的逻辑
}

内容的提问来源于stack exchange,提问作者LeO

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:22:52