Spring Boot 3中无法使用EhCacheCacheManager的解决方案咨询
Spring Boot 3迁移EhCache解决方案
一、兼容旧版EhCache 2.x(最小改动)
Spring Boot 3依赖的Spring Framework 6已移除官方对net.sf.ehcache(EhCache 2.x)的集成类(如EhCacheCacheManager),若要保留原有EhCache 2.7.4配置,需手动实现Spring Cache适配类:
1. 自定义Cache适配类
import net.sf.ehcache.Cache; import net.sf.ehcache.Element; import org.springframework.cache.support.AbstractValueAdaptingCache; import org.springframework.lang.Nullable; public class EhCache2Cache extends AbstractValueAdaptingCache { private final Cache ehcache; public EhCache2Cache(Cache ehcache) { super(true); this.ehcache = ehcache; } @Override protected Object lookup(Object key) { Element element = this.ehcache.get(key); return (element != null ? element.getObjectValue() : null); } @Override public String getName() { return this.ehcache.getName(); } @Override public Object getNativeCache() { return this.ehcache; } @Override public void put(Object key, @Nullable Object value) { this.ehcache.put(new Element(key, value)); } @Override @Nullable public ValueWrapper putIfAbsent(Object key, @Nullable Object value) { Element existing = this.ehcache.putIfAbsent(new Element(key, value)); return toValueWrapper(existing != null ? existing.getObjectValue() : null); } @Override public void evict(Object key) { this.ehcache.remove(key); } @Override public void clear() { this.ehcache.removeAll(); } }
2. 自定义CacheManager适配类
import net.sf.ehcache.CacheManager; import org.springframework.cache.Cache; import org.springframework.cache.support.AbstractCacheManager; import java.util.Collection; import java.util.stream.Collectors; public class EhCache2CacheManager extends AbstractCacheManager { private final CacheManager ehcacheManager; public EhCache2CacheManager(CacheManager ehcacheManager) { this.ehcacheManager = ehcacheManager; } @Override protected Collection<? extends Cache> loadCaches() { return this.ehcacheManager.getCacheNames().stream() .map(name -> new EhCache2Cache(this.ehcacheManager.getCache(name))) .collect(Collectors.toList()); } }
3. 修改原有配置类
仅替换cacheManager()方法的实现,保留原有EhCache配置逻辑:
import net.sf.ehcache.config.CacheConfiguration; import org.springframework.cache.annotation.CachingConfigurer; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.List; @Configuration @EnableCaching public class AppConfig implements CachingConfigurer { private static final List<String> CACHE_LIST = List.of("entity1", "entity2", "entity3"); @Bean(destroyMethod = "shutdown") public net.sf.ehcache.CacheManager ehCacheManager() { final net.sf.ehcache.config.Configuration configuration = new net.sf.ehcache.config.Configuration(); for (final String cacheComponent : CACHE_LIST) { final CacheConfiguration cacheConfiguration = new CacheConfiguration(); cacheConfiguration.setName(cacheComponent); cacheConfiguration.setMemoryStoreEvictionPolicy("LFU"); cacheConfiguration.setMaxEntriesLocalHeap(10000); cacheConfiguration.setOverflowToOffHeap(false); cacheConfiguration.setEternal(false); configuration.addCache(cacheConfiguration); } return net.sf.ehcache.CacheManager.newInstance(configuration); } @Bean @Override public org.springframework.cache.CacheManager cacheManager() { return new EhCache2CacheManager(ehCacheManager()); } }
二、升级至EhCache 3.x(无XML配置方案)
若无法兼容旧版本,推荐升级到EhCache 3.x,Spring Boot 3对其有原生支持,无XML配置步骤如下:
1. 更新依赖
移除net.sf.ehcache依赖,引入Spring Boot缓存starter和EhCache 3:
<!-- Maven依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> <dependency> <groupId>org.ehcache</groupId> <artifactId>ehcache</artifactId> </dependency>
2. 新配置类实现
使用EhCache 3的API构建缓存配置:
import org.ehcache.config.builders.CacheConfigurationBuilder; import org.ehcache.config.builders.CacheManagerBuilder; import org.ehcache.config.builders.ResourcePoolsBuilder; import org.ehcache.config.units.EntryUnit; import org.ehcache.expiry.Duration; import org.ehcache.expiry.Expirations; import org.springframework.cache.annotation.CachingConfigurer; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.jcache.JCacheCacheManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.List; import java.util.concurrent.TimeUnit; @Configuration @EnableCaching public class AppConfig implements CachingConfigurer { private static final List<String> CACHE_LIST = List.of("entity1", "entity2", "entity3"); @Bean(destroyMethod = "close") public javax.cache.CacheManager jCacheManager() { CacheManagerBuilder<org.ehcache.CacheManager> cacheManagerBuilder = CacheManagerBuilder.newCacheManagerBuilder(); for (String cacheName : CACHE_LIST) { cacheManagerBuilder.withCache(cacheName, CacheConfigurationBuilder.newCacheConfigurationBuilder(Object.class, Object.class, ResourcePoolsBuilder.newResourcePoolsBuilder() .heap(10000, EntryUnit.ENTRIES)) // 替代原eternal=false,设置TTL为永不过期可改用Duration.INFINITE .withExpiry(Expirations.timeToLiveExpiration(Duration.of(30, TimeUnit.MINUTES))) // 配置LFU淘汰策略 .withEvictionPolicy(org.ehcache.config.EvictionPolicy.LFU)); } org.ehcache.CacheManager ehcacheManager = cacheManagerBuilder.build(true); return javax.cache.Caching.getCachingProvider().getCacheManager(ehcacheManager.getURI(), ehcacheManager.getClassLoader()); } @Bean @Override public org.springframework.cache.CacheManager cacheManager() { return new JCacheCacheManager(jCacheManager()); } }
配置说明
heap(10000, EntryUnit.ENTRIES)对应原配置的maxEntriesLocalHeap=10000withExpiry替代原eternal=false,示例设置30分钟TTL,需根据业务调整withEvictionPolicy直接配置LFU淘汰策略,比旧版更简洁
内容的提问来源于stack exchange,提问作者Abhi V
相关产品推荐
相关产品推荐

