使用@CacheEvict注解是否可以清除匹配指定模式的缓存key?
Spring Cache 通配符批量清除缓存的实现方案
Spring 原生的 @CacheEvict 注解不直接支持通配符匹配批量删除指定前缀的缓存key,这个特性没有作为通用抽象能力内置的原因是不同缓存中间件的底层实现逻辑差异较大,没有统一的标准实现方式。不过可以通过以下两种常见方案实现需求:
- 方案1:适配特定缓存中间件实现(以Redis为例)
如果你的项目使用Redis作为缓存底层,可以直接通过Redis的模式匹配能力实现前缀删除,示例代码如下:
import org.springframework.data.redis.cache.RedisCache; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.beans.factory.annotation.Autowired; import java.nio.charset.StandardCharsets; import java.util.Set; public class CacheService { @Autowired private RedisCacheManager redisCacheManager; public void evictBazPrefixCache() { RedisCache fooCache = (RedisCache) redisCacheManager.getCache("FOO"); if (fooCache == null) { return; } // 拼接带缓存前缀的匹配规则 String matchPattern = fooCache.getCacheConfiguration().getKeyPrefixFor("FOO") + "baz*"; // 执行批量删除 fooCache.getNativeCache().execute(connection -> { Set<byte[]> matchKeys = connection.keys(matchPattern.getBytes(StandardCharsets.UTF_8)); if (!matchKeys.isEmpty()) { connection.del(matchKeys.toArray(new byte[0][])); } return null; }); } }
如果需要注解式的调用方式,你可以自定义一个支持前缀匹配的缓存清除注解,配合AOP拦截实现上述逻辑即可。
- 方案2:通用缓存分组方案(不绑定底层缓存实现)
如果需要适配多种缓存中间件,可以调整缓存分组策略,把所有baz前缀的缓存单独归到一个独立的缓存命名空间下,直接使用原生注解的全量清除属性即可:
// 清除整个BAZ_GROUP缓存分组下的所有key @CacheEvict(value = "BAZ_GROUP", allEntries = true) public void cleanBazCache() { // 业务逻辑 }
这个方案的缺点是需要提前规划缓存分组,适合批量删除逻辑固定的场景。
内容的提问来源于stack exchange,提问作者Peter Catalin
相关产品推荐
相关产品推荐

