从Spring中的异步函数调用Cache时不会刷新
问题描述:
我正在调用一个函数,它具有CacheEvict
注释。这是从一个本身被异步执行的函数调用的。从Spring中的异步函数调用Cache时不会刷新
似乎缓存没有被执行后,功能已被驱逐。
下面是示例代码
@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
。这两个功能都存在于服务中。现在,这个配置是否正确?如果是,可能是缓存没有被清除的可能原因是什么?
任何帮助表示赞赏。提前致谢。
答
我认为你的问题在于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错误,并将按原样存档。
它现在是https://jira.spring.io/browse/SPR-15915 – Henri
我已经尝试过'this',但它没有工作。我不知道“这个”与豆有所不同(我的错误)。所以现在,我现在已经移除了注解,并使用CacheManager驱逐所需的缓存。虽然我不确定它有多正确。 –
通过'this'我的意思是注入代理。就像我的代码示例中一样。这工作。我试过了。 – Henri