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

Mixing declarative and imperative JCache configurations

我正在尝试以声明式和命令式配置的混合方式设置 (J) 缓存,因为 JCache 标准没有提供限制缓存可以占用的最大大小的方法。我想尽可能 "provider independent" 这样做,这样我以后可以灵活地更换供应商。目前我有使用 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 对其进行了测试),这对于创建我的缓存并将其与注释和命令式代码一起使用都非常有效。

现在我需要使用专有配置限制所有缓存的最大大小。我需要一个 common/default 配置,该配置将应用于该提供者创建的任何缓存,而不管它们的其他特定特征(过期策略、生存时间等)是由命令式配置设置的。

在包含配置文件时,我一直遇到问题,因为缓存管理器配置有配置文件,用于创建在我的 yaml 文件中声明的这些缓存。有 ideas/suggestions 吗?我记得在某处读过在 Ehcache 配置中使用 *,但我再也找不到那个页面了。

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

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

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

我会把我的发现放在这里作为参考。

Hazelcast

正如 mdogan 所回复的,Hazelcast 不支持这一点。它具有 configurations with wildcards (check ) 的概念,但这些不适用于以编程方式配置的缓存。

Ehcache

在Ehcache中我找到了一个方法。根据 their documentation:

Configure a default template from which all programmatically created Cache instances inherit

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

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

并在该缓存中设置您喜欢的所有配置。这种声明式配置补充甚至覆盖了编程式配置。可以找到有关如何指定 Ehcache 最大大小的指示 here