2017-08-29 104 views
0

我正在調用一個函數,它具有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。這兩個功能都存在於服務中。現在,這個配置是否正確?如果是,可能是緩存沒有被清除的可能原因是什麼?

任何幫助表示讚賞。提前致謝。

回答

1

我認爲你的問題在於Spring代理不可重入。爲了實現AsyncCacheEvict,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錯誤,並將按原樣存檔。

+0

它現在是https://jira.spring.io/browse/SPR-15915 – Henri

+0

我已經嘗試過'this',但它沒有工作。我不知道「這個」與豆有所不同(我的錯誤)。所以現在,我現在已經移除了註解,並使用CacheManager驅逐所需的緩存。雖然我不確定它有多正確。 –

+0

通過'this'我的意思是注入代理。就像我的代碼示例中一樣。這工作。我試過了。 – Henri