ejb构建_如何使用单例EJB,Ehcache和MBean构建和清除参考数据缓存
ejb構建
 在本文中,我將介紹如何使用單例EJB和Ehcache在Java EE中構建簡單的參考數據緩存。 高速緩存將在給定的時間段后重置自身,并且可以通過調用REST端點或MBean方法“手動”清除。 這篇文章實際上是建立在以前的文章中如何建立和清除與單EJB和MBean的一個參考的數據高速緩存 ; 唯一的區別是,我將使用Ehcache緩存,而不是將數據存儲在ConcurrentHashMap<String, Object> ,并且該緩存能夠通過Ehcache方式進行更新。 
1.快取
原來這是一個只讀緩存,可以從外部刷新它。 我希望將緩存作為服務的一種包裝,為應用程序提供實際的參考數據–帶代碼的AOP樣式!
接口
參考數據的簡單界面
@Local public interface ReferenceDataCache {/*** Returns all reference data required in the application */ReferenceData getReferenceData();/*** evict/flush all data from cache */void evictAll(); }緩存功能定義了兩種簡單的方法:
- getReferenceData() –緩存所有不同來源在后臺收集的參考數據
- evictAll() –調用方法以完全清除緩存
實作
使用Ehcache的簡單參考數據緩存實現
@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER) @Singleton public class ReferenceDataCacheBean implements ReferenceDataCache {private static final String ALL_REFERENCE_DATA_KEY = "ALL_REFERENCE_DATA";private static final int CACHE_MINUTES_TO_LIVE = 100;private CacheManager cacheManager;private Cache refDataEHCache = null; @EJBReferenceDataLogic referenceDataService; @PostConstructpublic void initialize(){ cacheManager = CacheManager.getInstance();CacheConfiguration cacheConfiguration = new CacheConfiguration("referenceDataCache", 1000);cacheConfiguration.setTimeToLiveSeconds(CACHE_MINUTES_TO_LIVE * 60);refDataEHCache = new Cache(cacheConfiguration );cacheManager.addCache(refDataEHCache);}@Override@Lock(LockType.READ)public ReferenceData getReferenceData() {Element element = refDataEHCache.get(ALL_REFERENCE_DATA_KEY);if(element != null){ return (ReferenceData) element.getObjectValue();} else {ReferenceData referenceData = referenceDataLogic.getReferenceData();refDataEHCache.putIfAbsent(new Element(ALL_REFERENCE_DATA_KEY, referenceData));return referenceData;} }@Overridepublic void evictAll() {cacheManager.clearAll();} ........... }注意:
- @Singleton –可能是此類中最重要的代碼行。 此注釋指定在應用程序中將僅存在一個這種類型的bean的單例。 該bean可以由多個線程同時調用。
現在讓我們將代碼分解為不同的部分:
緩存初始化
@PostConstruct注釋用于在依賴項注入完成后需要執行的方法上,以執行任何初始化–在我們的情況下,是創建和初始化(eh)緩存。
緩存初始化
@PostConstructpublic void initialize(){ cacheManager = CacheManager.create();CacheConfiguration cacheConfiguration = new CacheConfiguration("referenceDataCache", 1000);cacheConfiguration.setTimeToLiveSeconds(CACHE_MINUTES_TO_LIVE * 60);refDataEHCache = new Cache(cacheConfiguration );cacheManager.addCache(refDataEHCache);}注意:此注釋只能注釋一種方法。
Ehcache的所有用法都始于創建CacheManager ,它是Ehcache的容器,可維護其生命周期的各個方面。 我使用CacheManager.create()方法,這是一種使用默認配置創建單例CacheManager的工廠方法,如果存在,則將其返回:
cacheManager = CacheManager.create();我通過提供緩存名稱(“ referenceDataCache”)和內存中最大元素數( maxEntriesLocalHeap )來構建CacheConfiguration對象,然后將它們逐出(0 ==無限制),最后我進行設置自元素創建之日起,元素的默認生存時間:
CacheConfiguration cacheConfiguration = new CacheConfiguration("referenceDataCache", 1000); cacheConfiguration.setTimeToLiveSeconds(CACHE_MINUTES_TO_LIVE * 60);現在,借助于CacheConfiguration對象,我以編程方式創建了我的參考數據緩存,并將其添加到CacheManager中。 請注意,只有將緩存添加到CacheManager后,它們才可用:
refDataEHCache = new Cache(cacheConfiguration ); cacheManager.addCache(refDataEHCache);注意:您也可以以聲明的方式創建緩存:創建CacheManager時,它將創建在配置中找到的緩存。 您可以通過指定配置文件的路徑,類路徑中的配置,InputStream中的配置或類路徑中的默認ehcache.xml文件來創建CacheManager。 查看Ehcache代碼示例以獲取更多信息。
從緩存中獲取數據
@Override @Lock(LockType.READ) public ReferenceData getReferenceData() {Element element = refDataEHCache.get(ALL_REFERENCE_DATA_KEY);if(element != null){ return (ReferenceData) element.getObjectValue();} else {ReferenceData referenceData = referenceDataLogic.getReferenceData();refDataEHCache.put(new Element(ALL_REFERENCE_DATA_KEY, referenceData));return referenceData;} }首先,我嘗試根據元素的鍵從緩存中獲取該元素,如果元素存在于緩存中( ==null ),則將從服務類接收該元素并將其放置在緩存中以供將來請求。
注意:
@Lock(LockType.READ)指定具有容器管理的并發性的單例bean的并發鎖定類型。 設置為LockType.READ ,它將強制執行該方法以允許對其進行完全并發訪問(假定未持有任何寫鎖)。 這正是我想要的,因為我只需要執行讀取操作。 另一個更保守的選項@Lock(LockType.WRITE)順便說一下是DEFAULT,它強制對bean實例的獨占訪問。 這應該在高度并發的環境中使方法變慢。
清除緩存
清除緩存
@Override public void evictAll() { cacheManager.clearAll(); }CacheManager的clearAll()方法清除CacheManager中所有緩存的內容,但不刪除任何緩存。 我在這里只是為了簡單起見使用它,因為我只有一個緩存,因此需要刷新。
注意:如果您有多個高速緩存,即多個高速緩存名稱,并且只想清除一個,則需要使用CacheManager.clearAllStartingWith(String prefix) ,該名稱以CacheManager開頭的名稱清除CacheManager中所有高速緩存的內容。前綴,但不刪除它們。
2.如何觸發緩存緩存
這篇文章的第二部分將討論清除緩存的可能性。 由于緩存實現是一個企業Java Bean,因此我們可以從MBean或從Web服務中調用它。
MBean
如果您不熟悉Java管理擴展(JMX), 這是一種Java技術,它提供用于管理和監視應用程序,系統對象,設備(例如打印機)和面向服務的網絡的工具。 這些資源由稱為MBeans(用于Managed Bean)的對象表示 ,我強烈建議您從本教程的路徑:Java管理擴展(JMX)開始。
接口
公開的方法僅允許通過JMX重置緩存:
@MXBean public interface CacheResetMXBean { void resetReferenceDataCache(); }“ MXBean是一種MBean,僅引用一組預定義的數據類型。 這樣,您可以確保您的MBean可被任何客戶端(包括遠程客戶端)使用,而無需客戶端有權訪問代表MBean類型的特定于模型的類。 MXBean提供了一種將相關值捆綁在一起的便捷方法,而無需將客戶端特別配置為處理捆綁。” [5]
實作
CacheReset MxBean實現
@Singleton @Startup public class CacheReset implements CacheResetMXBean {private MBeanServer platformMBeanServer;private ObjectName objectName = null;@EJBReferenceDataCache referenceDataCache;@PostConstructpublic void registerInJMX() {try {objectName = new ObjectName("org.codingpedia.simplecacheexample:type=CacheReset");platformMBeanServer = ManagementFactory.getPlatformMBeanServer();//unregister the mbean before registerting againSet<ObjectName> existing = platformMBeanServer.queryNames(objectName, null);if(existing.size() > 0){platformMBeanServer.unregisterMBean(objectName);}platformMBeanServer.registerMBean(this, objectName);} catch (Exception e) {throw new IllegalStateException("Problem during registration of Monitoring into JMX:" + e);}} @Overridepublic void resetReferenceDataCache() {referenceDataCache.evictAll();}}注意:
- 如前所述,該實現僅調用上一節中介紹的注入的單例bean的evictAll()方法
- 該bean也被定義為@Singleton
- @Startup批注導致在應用程序啟動時由容器實例化Bean – 渴望初始化
- 我再次使用@PostConstruct功能。 在這里, 此 bean已在JMX中注冊,如果有的話,請檢查是否使用ObjectName將其刪除。
休息服務電話
我還內置了通過調用REST資源清除緩存的可能性。 在(rest-context)/ reference-data / flush-cache上執行HTTP POST時會發生這種情況:
通過REST資源觸發緩存刷新
@Path("/reference-data") public class ReferenceDataResource {@EJBReferenceDataCache referenceDataCache;@POST@Path("flush-cache")public Response flushReferenceDataCache() {referenceDataCache.evictAll();return Response.status(Status.OK).entity("Cache successfully flushed").build();} @GET@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })public Response getReferenceData(@QueryParam("version") String version) {ReferenceData referenceData = referenceDataCache.getReferenceData(); if(version!=null && version.equals(referenceData.getVersion())){return Response.status(Status.NOT_MODIFIED).entity("Reference data was not modified").build(); } else {return Response.status(Status.OK).entity(referenceData).build(); }} }注意@GET getReferenceData(...)方法中存在版本查詢參數。 這表示參考數據上的哈希,如果尚未修改,則客戶端將收到304未修改HTTP狀態 。 這是節省帶寬的好方法,尤其是在您擁有移動客戶端的情況下。 有關REST服務設計和實現的詳細討論,請參閱我的教程“使用Jersey和Spring的Java REST API設計和實現”。
注意:在集群環境中,當參考數據更改時,需要在部署了應用程序的每個JVM上調用resetCache(…)。
好,就是這樣。 在本文中,我們學習了如何借助Ehcache在Java EE中構建簡單的參考數據緩存。 當然,您可以輕松擴展緩存功能,以提供對緩存對象的更精細的訪問/清除。 在這種情況下,請不要忘記使用LockType.WRITE作為清除方法……
翻譯自: https://www.javacodegeeks.com/2014/11/how-to-build-and-clear-a-reference-data-cache-with-singleton-ejbs-ehcache-and-mbeans.html
ejb構建
總結
以上是生活随笔為你收集整理的ejb构建_如何使用单例EJB,Ehcache和MBean构建和清除参考数据缓存的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 华为P20能插内存卡吗
- 下一篇: listview属性_属性提取器:获取L
