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

Spring Boot自定义驱逐方法无法清除缓存问题咨询

问题原因及解决方案

核心问题不是evictByFooId缺少注解,而是Spring缓存注解基于AOP代理实现,类内部直接调用带缓存注解的方法不会触发代理逻辑。

你写的evictByFooId是直接调用同一个类里的evictByTestId,这时候走的是对象本身的方法调用,跳过了Spring生成的代理对象,所以evictByTestId上的@CacheEvict注解根本没生效,自然清不掉缓存。

几种可行的解决办法:

1. 注入自身代理对象调用

在类里注入当前类的代理实例,通过代理对象调用evictByTestId:

@Component
@CacheConfig(cacheNames = ["test"])
class TestCache {
    @Autowired
    private lateinit var selfProxy: TestCache

    @Cacheable(cacheNames = ["test"], key = "#testId")
    fun find(testId: String): String { ... }

    @CachePut(cacheNames = ["test"], key = "#testId")
    fun put(testId: String, set: String): String { ... }

    @CacheEvict(cacheNames = ["test"], key = "#testId")
    fun evictByTestId(testId: String) { }

    fun evictByFooId(fooId: String): Boolean {
        /* some processing to convert fooId to testId */
        val testId = fooId
        selfProxy.evictByTestId(testId)
        return true
    }
}

2. 直接给evictByFooId加@CacheEvict注解

如果fooId转testId的逻辑可以用SpEL表达式实现,直接在evictByFooId上标注注解,把转换逻辑写到key里:

@Component
@CacheConfig(cacheNames = ["test"])
class TestCache {
    @Cacheable(cacheNames = ["test"], key = "#testId")
    fun find(testId: String): String { ... }

    @CachePut(cacheNames = ["test"], key = "#testId")
    fun put(testId: String, set: String): String { ... }

    @CacheEvict(cacheNames = ["test"], key = "#testId")
    fun evictByTestId(testId: String) { }

    @CacheEvict(cacheNames = ["test"], key = "#fooId") // 替换成实际转换逻辑,比如T(com.yourpackage.Utils).convertFooToTest(#fooId)
    fun evictByFooId(fooId: String): Boolean {
        return true
    }
}

3. 拆分逻辑到独立组件

把缓存操作的逻辑抽成单独的组件,比如TestCacheManager,然后在TestCache里注入这个组件调用,这样调用就会走代理:

@Component
class TestCacheManager {
    @CacheEvict(cacheNames = ["test"], key = "#testId")
    fun evictByTestId(testId: String) { }
}

@Component
@CacheConfig(cacheNames = ["test"])
class TestCache {
    @Autowired
    private lateinit var cacheManager: TestCacheManager

    @Cacheable(cacheNames = ["test"], key = "#testId")
    fun find(testId: String): String { ... }

    @CachePut(cacheNames = ["test"], key = "#testId")
    fun put(testId: String, set: String): String { ... }

    fun evictByFooId(fooId: String): Boolean {
        val testId = fooId
        cacheManager.evictByTestId(testId)
        return true
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 10:25:23