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

Spring Infinispan缓存对象过期时间设置方案咨询(旧版本)

适配旧版Infinispan Spring集成的缓存过期时间配置方案

针对你使用的infinispan-spring3和infinispan-client-hotrod 6.4.0.Final-redhat-4版本,从手动操作RemoteCache切换到Spring缓存注解后,要实现类似的过期时间设置,这里有几个适配该旧版本的可行方案:

方案1:在SpringRemoteCacheManager配置中设置全局默认TTL

既然你用的是XML配置的SpringRemoteCacheManager,可以在配置时给它绑定的HotRod客户端设置全局默认的缓存过期时间,对应你之前手动设置的15分钟:

<bean id="springRemoteCacheManager" class="org.infinispan.spring.remote.provider.SpringRemoteCacheManager">
    <constructor-arg>
        <bean class="org.infinispan.client.hotrod.RemoteCacheManager">
            <constructor-arg>
                <bean class="org.infinispan.client.hotrod.configuration.ConfigurationBuilder">
                    <!-- 配置JDG服务器地址 -->
                    <property name="serverList" value="your-jdg-host:11222"/>
                    <!-- 配置全局缓存过期规则 -->
                    <property name="expiration">
                        <bean class="org.infinispan.client.hotrod.configuration.ExpirationConfiguration">
                            <!-- 15分钟转换为毫秒:15*60*1000=900000 -->
                            <property name="lifespan" value="900000"/>
                        </bean>
                    </property>
                </bean>
            </constructor-arg>
        </bean>
    </constructor-arg>
</bean>

这个配置会让所有通过该CacheManager创建的缓存条目,默认都拥有15分钟的存活时间,和你之前手动调用cache.put(key, value, 15, TimeUnit.MINUTES)的效果一致。

方案2:在JDG服务器端为特定缓存配置TTL

如果不同缓存需要不同的过期时间,或者你希望把缓存规则集中在服务器端管理,可以直接修改JDG服务器的配置文件(比如standalone.xml或domain.xml),给指定名称的缓存设置TTL:

<cache-container name="default" default-cache="local">
    <!-- 这里以分布式缓存为例,根据你的实际缓存类型调整 -->
    <distributed-cache name="user-cache" mode="SYNC">
        <!-- 设置该缓存的条目过期时间为15分钟 -->
        <expiration lifespan="900000"/>
    </distributed-cache>
</cache-container>

之后在代码中用@Cacheable(value = "user-cache")时,该缓存下的所有条目就会自动按照服务器端配置的15分钟过期。

方案3:自定义CacheResolver实现动态条目级TTL(适合灵活场景)

如果需要针对不同方法甚至不同条目设置不同的过期时间,这个旧版本的Spring集成没有直接支持注解参数配置TTL,但可以通过自定义CacheResolver结合AOP来实现:

步骤1:定义自定义TTL注解

先创建一个注解,用来标记方法需要的过期时间:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CacheTimeToLive {
    long value();
    TimeUnit unit() default TimeUnit.MINUTES;
}

步骤2:实现自定义CacheResolver

通过这个Resolver,我们可以拿到底层的RemoteCache,并结合注解设置TTL:

public class TtlCustomCacheResolver implements CacheResolver {
    private final CacheManager cacheManager;

    public TtlCustomCacheResolver(CacheManager cacheManager) {
        this.cacheManager = cacheManager;
    }

    @Override
    public Collection<? extends Cache> resolveCaches(CacheOperationInvocationContext<?> context) {
        // 获取当前方法的TTL注解
        CacheTimeToLive ttlAnnotation = context.getMethod().getAnnotation(CacheTimeToLive.class);
        if (ttlAnnotation != null) {
            long ttlMillis = ttlAnnotation.unit().toMillis(ttlAnnotation.value());
            // 遍历当前方法关联的缓存
            for (String cacheName : context.getOperation().getCacheNames()) {
                Cache springCache = cacheManager.getCache(cacheName);
                if (springCache instanceof SpringRemoteCache) {
                    // 获取原生的RemoteCache实例
                    RemoteCache<Object, Object> remoteCache = ((SpringRemoteCache) springCache).getNativeCache();
                    // 如果需要全局修改该缓存的TTL,可设置;如果需要条目级,后续结合AOP拦截put操作
                    // remoteCache.getConfiguration().expiration().lifespan(ttlMillis);
                }
            }
        }
        // 返回对应的缓存集合
        return context.getOperation().getCacheNames().stream()
                .map(cacheManager::getCache)
                .collect(Collectors.toList());
    }
}

步骤3:配置Spring缓存使用自定义Resolver

在XML中配置缓存注解驱动和自定义Resolver:

<cache:annotation-driven cache-resolver="ttlCustomCacheResolver"/>

<bean id="ttlCustomCacheResolver" class="com.yourcompany.cache.TtlCustomCacheResolver">
    <constructor-arg ref="springRemoteCacheManager"/>
</bean>

步骤4:在业务方法上使用

@Cacheable(value = "order-cache", cacheResolver = "ttlCustomCacheResolver")
@CacheTimeToLive(15)
public Order getOrder(String orderId) {
    // 业务逻辑:从DB查询订单
    return orderRepository.findById(orderId);
}

如果需要更细粒度的条目级TTL,可以额外添加Spring AOP切面,拦截缓存方法的返回结果,手动调用RemoteCache.put(key, value, ttl, unit)来设置,这样就能实现和之前手动操作完全一致的灵活控制。


补充:因为你用的是6.4.x的旧版本,这个版本的Infinispan Spring集成还没有支持新版本中@Cacheable注解直接配置expireAfterWrite的特性,所以上述三个方案是最适配当前环境的选择。优先推荐方案1或2,配置简单且维护成本低。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:21:13