我一直在高速緩存的名稱的靜態方法對此也有興趣。對不起,說,我還沒有找到任何這樣做的微不足道的方法。 Spring不會爲你做這件事,它更多的是什麼緩存實現彈簧包裝的問題可以做到這一點。我假設你正在使用EhCache實現。不幸的是,據我所知,這個功能並沒有出現。
有多種方法可以實現根據類似的東西在你的問題
1)使用一個永恆的緩存時間,並有一,二類線程週期性循環通過緩存數據刷新它。我沒有這樣做完全是,但Thread類需要必須是這個樣子:
@Autowired
EhCacheCacheManager ehCacheCacheManager;
...
//in the infinite loop
List keys = ((Ehcache) ehCacheCacheManager.getCache("test").getNative Cache()).getKeys();
for (int i = 0; i < keys.size(); i++) {
Object o = keys.get(i);
Ehcache ehcache = (Ehcache)ehCacheCacheManager.getCache("test").getNativeCache()
Element item = (ehcache).get(o);
//get the data based on some info in the value, and if no exceptions
ehcache.put(new Element(element.getKey(), newValue));
}
- 好處是這是非常快的@Cacheable來電者,不足之處是你的服務器可能會得到更多的點擊比需要的要多
2)你可以讓一個CacheListener來偵聽驅逐事件,臨時存儲數據。如果服務器調用失敗,請使用該數據並從方法返回。
的ehcache.xml中
<cacheEventListenerFactory class="caching.MyCacheEventListenerFactory"/>
</cache>
</ehcache>
工廠: 進口net.sf.ehcache.event.CacheEventListener; import net.sf.ehcache.event.CacheEventListenerFactory; import java.util.Properties;
public class MyCacheEventListenerFactory extends CacheEventListenerFactory {
@Override
public CacheEventListener createCacheEventListener(Properties properties) {
return new CacheListener();
}
}
僞實施 進口net.sf.ehcache.CacheException; import net.sf.ehcache.Ehcache; import net.sf.ehcache.Element; 導入net.sf.ehcache.event。CacheEventListener;
import java.util.concurrent.ConcurrentHashMap;
public class CacheListener implements CacheEventListener {
//prob bad practice to use a global static here - but its just for demo purposes
public static ConcurrentHashMap myMap = new ConcurrentHashMap();
@Override
public void notifyElementPut(Ehcache ehcache, Element element) throws CacheException {
//we can remove it since the put happens after a method return
myMap.remove(element.getKey());
}
@Override
public void notifyElementExpired(Ehcache ehcache, Element element) {
//expired item, we should store this
myMap.put(element.getKey(), element.getValue());
}
//....
}
- 這裏的挑戰是,關鍵是不是很有用,您可能需要存儲有關返回值的關鍵的東西能夠在服務器調用失敗,把它撿起來。這感覺有點冒失,我還沒有確定這是否完全符合防彈要求。它可能需要一些測試。
3)很多的努力,但工作原理:
@Cacheable("test")
public MyObject getValue(String data) {
try {
MyObject result = callServer(data);
storeResultSomewhereLikeADatabase(result);
} catch (Exception ex) {
return getStoredResult(data);
}
}
一個臨這裏是它將重新啓動服務器之間的工作,你可以擴展它只是允許羣集服務器之間共享緩存。 我在12個集羣環境中有一個版本,每個集羣首先檢查數據庫以查看是否有其他集羣首先獲得「昂貴」的數據,然後重複使用,而不是進行服務器調用。
一個小的變體也可以使用第二個@Cacheable方法和@CachePut一起使用,而不是DB來存儲數據。但是這意味着內存使用量會翻一番。這可能是可以接受的,取決於你的結果大小。
這聽起來像是目標服務器需要2個調用,一個用於確定服務器是否啓動,另一個用於獲取實際數據。 2次調用意味着服務器可能在中間停機。 – zibi
也許使用該方法內的一些自定義邏輯可以幫助很多,但最終它不是一個大的改進尊重你建議作爲你的問題的主要選擇:( –