2017-04-21 59 views
0

我正在使用球衣(JAX-RS)編寫REST服務。本質上,它應該執行以下操作:保留並更新REST服務中的數據(JAX-RS)

有一個包含大量鍵=值對的文本文件。 REST服務的用戶應該能夠查詢密鑰並接收該值。

現在,爲每個查詢加載和分割整個文本文件需要很長時間。相反,我想將文本文件加載到Hashmap中並以固定間隔重新加載它。

我不知道如何實現此行爲,以便Hashmap在查詢之間存活,並且在重新加載數據時查詢REST服務不會導致併發問題。

我該如何在我的應用程序中擁有這樣的「緩存」?

回答

1

JAX-RS默認資源生命週期是按請求(請求範圍),因此您需要將資源標記爲@Singleton,以使其在併發請求之間共享。

@Singleton

javax.inject.Singleton

在該範圍有每JAX-RS應用只有一個實例。 Singleton資源可以使用@Singleton註釋,並且它的類可以使用Application的實例註冊。您也可以通過在應用程序中註冊單例實例來創建單例。

Life-cycle of Root Resource Classes

接下來,你需要實現一個定期刷新線程安全的高速緩存來存儲你的地圖。

我通常會用Guava CacheBuilder做到這一點:

private final LoadingCache<Object,Map<String,String>> cache; 
protected final Object CACHE_KEY = new Object();  

//Create a Cache and keep it in the instance variable 
public MyClass() { 
    this.cache = CacheBuilder.newBuilder() 
     .maximumSize(1) 
     .refreshAfterWrite(10,TimeUnit.MINUTES) 
     .build(new CacheLoader<Object,Map<String,String>>() { 
      @Override 
      public Map<String, String> load(Object key) { 
       //Parse your file and return a Map<String,String> 
      } 
     }); 
} 

@GET 
public void doIt() { 
     //Get a cached copy of your Map 
     Map<String,String> values = cache.get(CACHE_KEY); 
} 

緩存實例是安全的跨多個線程使用(雖然你還是要照顧對象的線程安全的,你從緩存中返回),並會在10分鐘內自動刷新一次。

在一個更復雜的系統中,您可能還想在別處創建LoadingCache實例,並將其注入到資源類中(在這種情況下,您可以將其保留爲請求範圍)。