不使用XML,如何配置Ehcache 3 + Spring Boot + Java Config?

23

我使用Ehcache 2 + Spring Boot。这是我的配置:

@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.

现在我想使用Ehcache 3 + spring bootJava config代替xml,但我没有找到任何示例。我的问题:

1)为什么几乎所有的示例都基于xml?如何比java config更好?

2)如何在spring boot中使用java config配置Ehcache 3而不使用xml


2
你看到了这个吗? - Patrick
@Patrick在这篇文章中使用了XML配置。 - ip696
我认为 XML 配置的问题在于它将在所有环境(DEV、QA、STG、PROD)中保持静态,但是将配置放在 Java 中可以从配置服务器获取它(配置存储在 yml 文件中)。 - rogue lad
3个回答

15

下面是创建Ehcache管理器Bean的Java配置的等效代码。

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>

2
如果您的缓存方法没有任何参数,您可以使用 SimpleKey 作为键类型配置。CacheConfigurationBuilder<SimpleKey, String> configuration = ... - Junyoung Oh

7

3

我更喜欢使用Java配置而不是XML配置。以下有两个代码示例,它们执行相同的逻辑但风格不同。

XML方法:

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方法:

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;
    }

}

1
你的XML和Java方法似乎是一样的。 - Jaumzera
我有两个程序模块,每个模块都有一个EhCacheManager;其中一个模块有它自己的缓存,另一个模块也有自己的缓存,它们不共享,并且已在JMX中注册。但是当我运行我的应用程序时,我会收到InstanceAlreadyExistsException异常。我该如何同时运行这两个模块并在JMX中显示仅两个实例? - javiergarval

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接