混合声明式和命令式JCache配置

时间:2018-10-11 19:49:28

标签: spring-boot ehcache configuration-files hazelcast jcache

我正在尝试以声明性和命令性配置的方式设置(J)缓存,因为JCache标准没有提供限制缓存可以占用的最大大小的方法。我想尽可能地做到“独立于提供商”,因此将来我可以灵活地更改提供商。我认为,目前我只能使用Java 7,因此咖啡因被废弃了。

我在我的application.yaml中保留了缓存列表及其条目的持续时间(TTL),该列表是通过属性加载器获得的。然后,使用以下代码创建缓存:

@Bean
public List<Cache<Object, Object>> getCaches() {
    CacheManager cacheManager = this.getCacheManager();
    List<Cache<Object, Object>> caches = new ArrayList();
    Map<String, String> cacheconfigs = this.cacheConfigPropertyLoader.getPropertyLoader().getCacheconfigs();
    Set<String> keySet = cacheconfigs.keySet();
    Iterator i$ = keySet.iterator();

    while(i$.hasNext()) {
        String name = (String)i$.next();
        String durationMinutes = (String)cacheconfigs.get(name);
        caches.add((new GenericDefaultCacheConfigurator.GenericDefaultCacheConfig(name, new Duration(TimeUnit.MINUTES, Long.valueOf(durationMinutes)))).getCache(cacheManager));
    }

    return caches;
}

@Bean
public CacheManager getCacheManager() {
    return Caching.getCachingProvider().getCacheManager();
}

private class GenericDefaultCacheConfig {
    public GenericDefaultCacheConfig(String cacheName, Duration duration) {
         public GenericDefaultCacheConfig(String id, Duration duration, Factory expiryPolicyFactory) {
        CACHE_ID = id;
        DURATION = duration;
        EXPIRY_POLICY = expiryPolicyFactory;
    }
    private MutableConfiguration<Object, Object> getCacheConfiguration() {
        return new MutableConfiguration<Object, Object>()
                    .setTypes(Object.class, Object.class)
                    .setStoreByValue(true)
                    .setExpiryPolicyFactory(EXPIRY_POLICY);
    }
    public Cache<Object, Object> getCache(CacheManager cacheManager) {
        CacheManager cm = cacheManager;
        Cache<K, V> cache = cm.getCache(CACHE_ID, Object.class, Object.class);
        if (cache == null)
           cache = cm.createCache(CACHE_ID, getCacheConfiguration());
        return cache;
    }
}

无论我在POM中使用了哪个JCache提供程序(我都使用org.jsr107.ri,hazelcast和EhCache对其进行了测试),这对于创建我的缓存并将其与注释和命令性代码一起使用都很好。

现在,我需要使用专有配置来限制所有缓存的最大大小。我需要一个通用/默认配置,该配置适用于该提供程序创建的任何缓存,而与强制性配置所设置的其他特定特征(到期策略,生存时间等)无关。

当包含配置文件时,使用配置文件配置用于创建在Yaml文件中声明的这些缓存的缓存管理器时,我一直遇到问题。有什么想法/建议吗?我记得曾经读过在Ehcache配置中使用*的地方,但是我再也找不到该页面。

2 个答案:

答案 0 :(得分:1)

Hazelcast JCache实现不支持混合声明式和命令式配置。

但是Hazelcast的CacheConfiguration实现CacheConfig允许传递CompleteConfiguration作为构造参数。 CacheConfig复制给定CompleteConfiguration的属性,然后您可以设置其他属性。

不是最好的方法,但是通过这种方法,您可以将标准缓存属性的配置和专有配置分开。

答案 1 :(得分:0)

我将我的发现放在这里,以便可以用作参考。

Hazelcast

正如mdogan回答的那样,Hazelcast不支持此功能。它具有configurations with wildcards(选中this reply)的概念,但不适用于以编程方式配置的缓存。

Ehcache

在Ehcache中,我找到了一种方法。根据{{​​3}}:

  

配置默认模板,所有以编程方式创建的Cache实例都将从该模板继承

您需要声明一个默认模板,如下所示:

<config
    xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
    xmlns='http://www.ehcache.org/v3'
    xmlns:jsr107='http://www.ehcache.org/v3/jsr107'
    xsi:schemaLocation="
        http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.0.xsd
        http://www.ehcache.org/v3/jsr107 http://www.ehcache.org/schema/ehcache-107-ext-3.0.xsd"> 

  <service> 
    <jsr107:defaults default-template="defCache"> 
    </jsr107:defaults>
  </service>

  <cache-template name="defCache">
    <heap unit="entries">20</heap>
  </cache-template>
</config>

,然后在该缓存中设置所需的所有配置。这种声明性配置补充或覆盖了程序性配置。可以在their documentation中找到有关如何指定Ehcache的最大大小的指示。