You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Thorntail应用中Infinispan作为JCache提供者的配置问题

解决JCache与Infinispan混合配置的冲突问题

你碰到的问题很典型——因为Infinispan通过XML配置提前创建了名为foo的缓存,而JSR-107规范要求CacheManager.createCache()在缓存已存在时必须抛出异常,所以你的代码才会报错。下面给你两种实用的解决方案,既能保留JCache的提供者无关性,又能搞定Infinispan的特定属性配置:

方案一:复用XML配置的缓存,统一管理所有属性

既然你已经在infinispan.xml里定义了Infinispan特定的acquire-timeout,那不如把JCache的标准属性也一并放到XML里配置,这样代码里只需要直接获取已存在的缓存即可,完全符合JCache规范,还能保持代码的提供者无关性。

第一步:修改infinispan.xml,加入JCache标准属性

Infinispan的XML配置支持直接定义JCache的标准属性,把你原本用代码设置的store-by-value、统计/管理开关都加进去:

<infinispan xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
            xsi:schemaLocation="urn:infinispan:config:9.4 http://www.infinispan.org/schemas/infinispan-config-9.4.xsd" 
            xmlns="urn:infinispan:config:9.4">
  <cache-container>
    <local-cache name="foo">
      <!-- Infinispan特定属性 -->
      <locking acquire-timeout="15000"/>
      <!-- JCache标准属性 -->
      <store-by-value/> <!-- 对应store-by-value=true -->
      <statistics enabled="false"/>
      <management enabled="false"/>
    </local-cache>
  </cache-container>
</infinispan>

第二步:修改produce方法,直接获取缓存

不需要再调用createCache,直接从CacheManager获取已配置好的缓存:

@Produces
@FooCache
public Cache<Long, DiscountOrAddition> getDiscoCache(CacheManager mgr) {
    // 直接获取XML中定义的"foo"缓存
    return mgr.getCache("foo");
}

这个方案的优势是代码完全基于JCache标准API,没有绑定到Infinispan——如果以后换其他JCache提供者,只需要替换对应的配置文件就行,代码不用改。

方案二:通过代码同时配置JCache和Infinispan属性

如果你更倾向于用代码管理所有配置,Infinispan的JCache实现允许你通过它的配置构建器,同时设置标准JCache属性和Infinispan特定属性,再创建缓存。不过这个方案会引入Infinispan的API依赖,稍微损失一点提供者无关性,但胜在配置集中在代码里。

代码示例:

@Produces
@FooCache
public Cache<Long, DiscountOrAddition> createDiscoCache(CacheManager mgr) {
    // 创建Infinispan配置构建器
    InfinispanConfigurationBuilder ispnBuilder = new InfinispanConfigurationBuilder();
    
    // 设置Infinispan特定属性
    ispnBuilder.locking().acquireTimeout(15000);
    
    // 设置JCache标准属性
    ispnBuilder.jcache()
               .storeByValue(true)
               .statistics(false)
               .management(false);
    
    // 构建JCache兼容的配置
    Configuration<Long, DiscountOrAddition> config = ispnBuilder.build();
    
    // 尝试创建缓存,若已存在则会抛出异常,所以可以先判断缓存是否存在
    try {
        return mgr.createCache("foo", config);
    } catch (CacheExistsException e) {
        return mgr.getCache("foo");
    }
}

为什么原来的方案会失败?

这是JSR-107规范的硬性要求:当调用createCache()时,如果同名缓存已经存在(比如你的XML在CacheManager初始化时就创建了foo),必须抛出CacheExistsException。所以你不能用createCache去覆盖已存在的缓存配置。

内容的提问来源于stack exchange,提问作者geca

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:35:41