EhCache:使用注释在多个对象上@CacheEvict



我知道使用 Spring 的 (3.1) 内置的 CacheManager 使用 EhCache 实现,在代理模式(默认)下存在某些限制,如这篇文章所示:

Spring 3.1 @Cacheable - 方法仍然执行

考虑一下我遇到的场景:

@CacheEvict(value = "tacos", key = "#tacoId", beforeInvocation = true)
removeTaco(String tacoId) {
    // Code to remove taco
}
removeTacos(Set<String> tacoIds) {
    for (String tacoId : tacoIds) {
        removeTaco(tacoId); 
    }
}

在这个存储库方法中,调用 removeTacos(tacoIds) 实际上不会从缓存中逐出任何内容,因为上述限制。 我的解决方法是,在上面的服务层上,如果我想删除多个炸玉米饼,我会遍历每个炸玉米饼 ID 并将其传递给 removeTaco(),并且永远不会使用 removeTacos()

但是,我想知道是否有另一种方法可以实现这一目标。

1) 是否有一个 SpEL 表达式可以传递给密钥,告诉 EhCache 使 Set 中的每个 id 过期?

e.g.  @CacheEvict(value = "tacos", key = "#ids.?[*]") // I know this isn't valid, just can't find the expression.

或者有没有办法让我删除Tacos()调用removeTaco并实际使缓存对象过期?

@Caching 注释可用于组合相同类型的多个注释,例如 @CacheEvict 或 @CachePut,这是 Spring 文档中的示例

@Caching(evict = { @CacheEvict("primary"), @CacheEvict(value="secondary", key="#p0") })
public Book importBooks(String deposit, Date date)

您可以执行以下两项操作之一

@CacheEvict(value = "tacos", allEntries = true)
removeTacos(Set<String> tacoIds)

如果炸玉米饼的阅读量比删除的多得多,那还不错

removeTacos(Set<String> tacoIds) {
    for (String tacoId : tacoIds) {
        getTacoService().removeTaco(tacoId); 
    }
}

通过调用服务(代理),可以调用缓存逐出。

AFAIK @CacheEvict仅支持删除单个条目(按键)或给定缓存中的所有条目,无法一次删除多个条目。如果你想从缓存中放置、更新或删除多个对象(使用注释),你可以切换到memcached,看看我的项目Simple Spring Memcached(SSM)。

自调用不通过代理,因此解决方案之一是切换到代理以外的其他模式。花药解决方案(我不推荐它)可能会保留对服务中的服务的引用(作为自动连线字段)并使用它来调用 removeTaco。

几个月前,我的一个项目中遇到了类似的问题。它没有使用Spring Cache,而是使用SSM,SSM也需要代理。为了使它工作,我将缓存(注释)从服务移动到 DAO(存储库)层。它解决了自调用的问题。

最新更新