当前位置: 首页 > 知识库问答 >
问题:

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

东门文斌
2023-03-14

我试图在声明性和命令式配置的混合中设置(J)缓存,因为JCache标准没有提供限制缓存可以占用的最大大小的方法。我想尽可能地“独立于提供者”,这样我将来就可以灵活地更改提供者。目前我有使用Java7的限制,所以我相信咖啡因被丢弃了。

我在应用程序中保留了缓存列表和它们条目的持续时间(TTL)。yaml,这是我用属性加载器得到的。然后,我用以下代码创建缓存:

@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个答案

岳嘉容
2023-03-14

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

Hazelcast公司

正如mdogan回答的那样,Hazelcast不支持这一点。它有通配符配置的概念(请查看此回复),但这些不适用于以编程方式配置的缓存。

Ehcache

在Ehcache中,我找到了一种方法。根据其文件:

配置默认模板,所有以编程方式创建的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>

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

祖麻雀
2023-03-14

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

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

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

 类似资料:
  • 本书到目前为止一直都在使用命令式编程,它使用编程语句改变程序状态。考虑下面这段简单的命令式程序。 def add(a, b): return a + b def fancy_func(a, b, c, d): e = add(a, b) f = add(c, d) g = add(e, f) return g fancy_func(1,

  • 问题内容: 我开始与go一起工作了几个星期,(再一次)我偶然发现了一些对我来说似乎很奇怪的东西: play 我想同时分配两个变量。一个已经被声明,在更好的范围内,另一个没有被声明。 它不起作用:编译器尝试重新声明前一个变量。但是,如果在同一范围内声明此变量,则效果很好。 这是为什么? 问题答案: 您所经历的通常称为 “可变阴影” 。当您使用在内部范围内的任何变量,包括像语句和尽管缺乏支撑的,一个新

  • 关于透明度 透明度极其密切地集成在 Illustrator 之中,您很可能在不知不觉间,就在图稿上加了透明度。您可以通过下列任意一种操作在图稿中添加透明度: 降低对象的不透明度,以使底层的图稿变得可见。 使用不透明蒙版来创建不同的透明度。 使用混合模式来更改重叠对象之间颜色的相互影响方式。 应用包含透明度的渐变和网格。 应用包含透明度的效果或图形样式,例如投影。 •导入包含透明度的 Adobe P

  • 问题内容: 最近,我一直在研究有关Facebook JavaScript库React.js的功能和使用方法。当其差异说话的JavaScript的世界往往是两种编程风格的休息和被mentionned。 两者有什么区别? 问题答案: 声明式的样式(如react所具有的样式)允许您通过说“它看起来像这样”来控制应用程序中的流程和状态。命令式风格可以解决这个问题,并允许您通过说“这是您应该做的”来控制应用

  • 我理解声明性管理和命令性管理之间的区别,在这个线程kubectl应用和kubectl创建中解释得很好?和官方文档https://kubernetes.io/docs/tasks/manage-kubernetes-objects/declarative-config/ 但我仍然怀疑的是,即使在声明式管理中 库贝特标度 尽管这种情况还会继续 Kubectl申请 命令在集群重启时仍然“无法存活”(因为

  • 我试图将我的编程风格从命令式切换到声明式,但有一些概念困扰着我,比如当涉及到循环时的性能。例如,我有一个原始数据,在操作它之后,我希望得到3个预期结果:itemsHash、namesHash、rangeItemsHash 为了达到预期的结果,命令式只循环一次,而声明式至少循环3次(、、)。哪一个比较好?在性能上有什么权衡吗?