How can I configure Ehcache 3 + spring boot + java config without xml?
Asked Answered
T

3

24

I use Ehcache 2 + spring boot. Here is my config:

@Bean
public CacheManager cacheManager() {
    return new EhCacheCacheManager(ehCacheCacheManager().getObject());
}

@Bean
public EhCacheManagerFactoryBean ehCacheCacheManager() {
    EhCacheManagerFactoryBean cmfb = new EhCacheManagerFactoryBean();
    cmfb.setConfigLocation(new ClassPathResource("ehcache.xml"));
    cmfb.setShared(true);
    return cmfb;
}

ehcache.xml - in resources.

Now I want to use Ehcache 3 + spring boot and Java config instead xml but I haven't found any example for this. My questions:

1) Why almost all examples are based on xml? How can this be better than java config?

2) How can I configure Ehcache 3 using java config in spring boot without using xml?

Thermae answered 19/10, 2018 at 11:54 Comment(3)
You see this?Safire
@Safire in this article use xml configThermae
I think the problem with xml config is that it will remain static across all environments (DEV, QA, STG, PROD) , but while having config in java gives a provision to get it from config server (config stored in yml files).Baskerville
M
17

Here is an equivalent java configuration for creating the Ehcache manager bean.

ApplicationConfig.java

@Configuration
@EnableCaching
public class ApplicationConfig {

    @Bean
    public CacheManager ehCacheManager() {
        CachingProvider provider = Caching.getCachingProvider();
        CacheManager cacheManager = provider.getCacheManager();

        CacheConfigurationBuilder<String, String> configuration =
                CacheConfigurationBuilder.newCacheConfigurationBuilder(
                        String.class,
                        String.class,
                     ResourcePoolsBuilder
                             .newResourcePoolsBuilder().offheap(1, MemoryUnit.MB))
                .withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofSeconds(20)));

        javax.cache.configuration.Configuration<String, String> stringDoubleConfiguration = 
Eh107Configuration.fromEhcacheCacheConfiguration(configuration);

            cacheManager.createCache("users", stringDoubleConfiguration);
            return cacheManager;

    }

}

ServiceImpl.java

@Service
public class ServiceImpl {

    @Cacheable(cacheNames = {"users"})
    public String getThis(String id) {
        System.out.println("Method called............");
        return "Value "+ id;
    }
}

pom.xml

     <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-cache</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>javax.cache</groupId>
        <artifactId>cache-api</artifactId>
    </dependency>
    <dependency>
        <groupId>org.ehcache</groupId>
        <artifactId>ehcache</artifactId>
    </dependency>
Metrist answered 5/1, 2021 at 17:56 Comment(1)
If your caching method doesn't have any parameter, you can use SimpleKey for key type configuration. CacheConfigurationBuilder<SimpleKey, String> configuration = ...Decile
T
8

There are a lot of examples. I personally am a fan of the Java configuration.

Here are the main official examples:

Tereus answered 31/10, 2018 at 17:20 Comment(0)
E
4

I prefer using JAVA configuration over XML configuration. There are two examples of code below, that do the same logic but are written in different styles.

XML approach:

import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.cache.support.CompositeCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.ClassPathResource;

import java.util.Collections;

@EnableCaching
@Configuration
public class CacheConfig {

    @Primary
    @Bean("cacheManager")
    public CompositeCacheManager cacheManager() {
        CompositeCacheManager compositeCacheManager = new CompositeCacheManager();
        compositeCacheManager.setFallbackToNoOpCache(true);
        compositeCacheManager.setCacheManagers(Collections.singleton(ehCacheManager()));
        return compositeCacheManager;
    }

    @Bean("ehCacheManager")
    public EhCacheCacheManager ehCacheManager() {
        EhCacheCacheManager ehCacheCacheManager = new EhCacheCacheManager();
        ehCacheCacheManager.setCacheManager(ehCacheManagerFactoryBean().getObject());
        return ehCacheCacheManager;
    }

    @Bean
    public EhCacheManagerFactoryBean ehCacheManagerFactoryBean() {
        EhCacheManagerFactoryBean ehCacheManagerFactoryBean = new EhCacheManagerFactoryBean();
        ehCacheManagerFactoryBean.setShared(true);
        ehCacheManagerFactoryBean.setConfigLocation(new ClassPathResource("ehcache.xml"));
        return ehCacheManagerFactoryBean;
    }

}

ehcache.xml

<ehcache name="custom_eh_cache">
    <diskStore path="java.io.tmpdir"/>
    <cache name="users"
           maxElementsInMemory="1000"
           eternal="false"
           timeToIdleSeconds="3600"
           timeToLiveSeconds="3600"
           memoryStoreEvictionPolicy="LRU"/>
    <cache name="roles"
           maxElementsInMemory="1000"
           eternal="false"
           timeToIdleSeconds="3600"
           timeToLiveSeconds="3600"
           memoryStoreEvictionPolicy="LRU"/>    
</ehcache>

JAVA approach:

import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.config.CacheConfiguration;
import net.sf.ehcache.config.DiskStoreConfiguration;
import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.cache.support.CompositeCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import java.util.Collections;

@EnableCaching
@Configuration
public class CacheConfig {

    @Primary
    @Bean("cacheManager")
    public CompositeCacheManager cacheManager() {
        CompositeCacheManager compositeCacheManager = new CompositeCacheManager();
        compositeCacheManager.setFallbackToNoOpCache(true);
        compositeCacheManager.setCacheManagers(Collections.singleton(ehCacheManager()));
        return compositeCacheManager;
    }

    @Bean("ehCacheManager")
    public EhCacheCacheManager ehCacheManager() {
        EhCacheCacheManager ehCacheCacheManager = new EhCacheCacheManager();
        ehCacheCacheManager.setCacheManager(getCustomCacheManager());
        return ehCacheCacheManager;
    }

    private CacheManager getCustomCacheManager() {
        CacheManager cacheManager = CacheManager.create(getEhCacheConfiguration());
        cacheManager.setName("custom_eh_cache");
        cacheManager.addCache(createCache("users"));
        cacheManager.addCache(createCache("roles"));
        return cacheManager;
    }

    private Cache createCache(String cacheName) {
        CacheConfiguration cacheConfig = new CacheConfiguration(cacheName, 1000)
                .memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LRU)
                .eternal(false)
                .timeToLiveSeconds(3600)
                .timeToIdleSeconds(3600);
        return new Cache(cacheConfig);
    }

    private net.sf.ehcache.config.Configuration getEhCacheConfiguration() {
        net.sf.ehcache.config.Configuration configuration = new net.sf.ehcache.config.Configuration();
        DiskStoreConfiguration diskStoreConfiguration = new DiskStoreConfiguration();
        diskStoreConfiguration.setPath("java.io.tmpdir");
        configuration.addDiskStore(diskStoreConfiguration);
        return configuration;
    }

}
Enplane answered 3/8, 2020 at 19:22 Comment(2)
Your XML and Java approach seems to be the same.Cardie
I have two modules with EhCacheManager each programatically; one with his Caches and the other with others, they aren't shared and they are registered in JMX. But when I run my app, I'm getting InstanceAlreadyExistsException. How can I run both and show the only two instances in JMX?Kristankriste

© 2022 - 2024 — McMap. All rights reserved.