我正在调用一个有CacheEvict
注释的函数。这是从一个本身异步执行的函数调用的。
执行该功能后似乎没有驱逐缓存。
以下是示例代码
@Async("executor1")
public void function1()
{
// do something
anotherFunction("name", 123, 12);
// do something more
}
@CacheEvict(cacheNames = {"cache1", "cache2", "cache3"}, key = "#testId")
public List<Integer> anotherFunction(String name, int testId, int packageId)
{
// some code here
}
我想要的是应该从所有缓存中清除对应于testId
的条目。
但是,在另一个电话中,我可以看到cache1
的旧条目。正在从控制器调用function1
。这两个功能都存在于服务中。现在,这个配置是否正确?如果是,那么缓存未被清除的可能原因是什么?
任何帮助表示赞赏。提前谢谢。
答案 0 :(得分:1)
我认为你的问题是Spring代理不是可重入的。为了实现Async
和CacheEvict
,Spring创建了一个代理。因此,在您的示例中,调用堆栈将是:
A -> B$$proxy.function1() -> B.function1() -> B.anotherFunction()
B$$proxy
包含异步和驱逐的逻辑。直接调用anotherFunction
时不适用。实际上,即使您删除了@Async
,它仍然无效。
您可以使用的技巧是将代理bean注入到类中。要改为委托代理this
。
public class MyClass {
private MyClass meWithAProxy;
@Autowired
ApplicationContext applicationContext;
@PostConstruct
public void init() {
meWithAProxy = applicationContext.getBean(MyClass.class);
}
@Async("executor1")
public void function1() {
meWithAProxy.anotherFunction("name", 123, 12);
}
@CacheEvict(cacheNames = "cache1", key = "#testId")
public List<Integer> anotherFunction(String name, int testId, int packageId) {
return Collections.emptyList();
}
}
有效。但是有一个问题。如果您现在直接致电anotherFunction
,则无法使用。我认为这是一个Spring bug,并将按原样提交。