Search code examples
javaspringehcachespring-cacheehcache-3

Converting Ehcache CacheManager (v 3.x) to Spring CacheManager without XML configuration


I'm trying to use Ehcache manager in my application. I would like to setup it without xml configuration. I have next dependencies:

<dependency>
    <groupId>org.ehcache</groupId>
    <artifactId>ehcache</artifactId>
    <version>3.6.0</version>
</dependency>
<dependency>
    <groupId>javax.cache</groupId>
    <artifactId>cache-api</artifactId>
    <version>1.0.0</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>5.1.1.RELEASE</version>
</dependency>

I have such CacheManager bean:

@Bean
public org.springframework.cache.CacheManager cacheManager() {
    org.ehcache.CacheManager mainPageCache = CacheManagerBuilder
            .newCacheManagerBuilder()
            .withCache("mainPageCache", CacheConfigurationBuilder
                    .newCacheConfigurationBuilder(
                            Pageable.class,
                            Collection.class,
                            ResourcePoolsBuilder.heap(10))
                    .withExpiry(ExpiryPolicyBuilder
                            .timeToLiveExpiration(Duration
                                    .of(10, ChronoUnit.SECONDS))))
            .build(true);
    // ...
}

Is it possible to convert Ehcache CacheManager to Spring CacheManager? I think there should be something like: return new JCacheCacheManager(/*some code*/);


Solution

  • You can't simply convert an ehcache CacheManager to a spring CacheManager.

    You can use org.ehcache.jsr107.EhcacheCachingProvider to get a javax.cache.CacheManager and give that to org.springframework.cache.jcache.JCacheCacheManager which is an implementation of org.springframework.cache.CacheManager for jcache (aka jsr107).

    import java.util.HashMap;
    import java.util.Map;
    
    import javax.cache.CacheManager;
    import javax.cache.Caching;
    
    import org.ehcache.config.CacheConfiguration;
    import org.ehcache.config.ResourcePools;
    import org.ehcache.config.builders.CacheConfigurationBuilder;
    import org.ehcache.config.builders.ResourcePoolsBuilder;
    import org.ehcache.config.units.EntryUnit;
    import org.ehcache.config.units.MemoryUnit;
    import org.ehcache.core.config.DefaultConfiguration;
    import org.ehcache.jsr107.EhcacheCachingProvider;
    import org.springframework.cache.annotation.EnableCaching;
    import org.springframework.cache.jcache.JCacheCacheManager;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    @EnableCaching
    public class CacheConfig {
    
    
        @Bean
        public JCacheCacheManager jCacheCacheManager() {
            JCacheCacheManager jCacheManager = new JCacheCacheManager(cacheManager());
            return jCacheManager;
        }
    
        @Bean(destroyMethod = "close")
        public CacheManager cacheManager() {
    
            ResourcePools resourcePools = ResourcePoolsBuilder.newResourcePoolsBuilder()
                    .heap(2000, EntryUnit.ENTRIES)
                    .offheap(100, MemoryUnit.MB)
                    .build();
    
    
            CacheConfiguration<Object,Object> cacheConfiguration = CacheConfigurationBuilder.newCacheConfigurationBuilder(
                    Object.class,
                    Object.class,
                    resourcePools).
                    build();
    
            Map<String, CacheConfiguration<?, ?>> caches = new HashMap<>();
            caches.put("myCache", cacheConfiguration);
    
            EhcacheCachingProvider provider = (EhcacheCachingProvider) Caching.getCachingProvider("org.ehcache.jsr107.EhcacheCachingProvider");
            org.ehcache.config.Configuration configuration = new DefaultConfiguration(caches, provider.getDefaultClassLoader());
    
            return  provider.getCacheManager(provider.getDefaultURI(), (org.ehcache.config.Configuration) configuration);
        }
    
    }
    

    If you're using spring-boot, it should auto configure the JCacheCacheManager for you. You can then use a JCacheManagerCustomizer to configure the cache.