Ehcache中監聽器有兩種,監聽CacheManager的CacheManagerEventListener和監聽Cache的CacheEventListener。在Ehcache中,Listener是通過對應的監聽器工廠來生產和發生作用的。下面我們將來介紹一下這兩種類型的監聽器。
1 CacheManager監聽器
Ehcache中定義了一個CacheManagerEventListener接口來監聽CacheManager的事件。CacheManagerEventListener可以監聽的事件有CacheManager添加和移除Cache。其中定義有如下五個方法:
public interface CacheManagerEventListener { void init() throws CacheException; Status getStatus(); void dispose() throws CacheException; void notifyCacheAdded(String cacheName); void notifyCacheRemoved(String cacheName); }
init方法會在CacheManagerEventListener實現類實例化后被調用,用於初始化CacheManagerEventListener。
l getStatus方法返回當前CacheManagerEventListener所處的狀態,可選值有STATUS_UNINITIALISED、 STATUS_ALIVE和STATUS_SHUTDOWN。
l dispose方法用於釋放資源。
l notifyCacheAdded方法會在往CacheManager中添加Cache時被調用。
l notifyCacheRemoved方法會在從CacheManager中移除Cache時被調用。
Ehcache是通過CacheManagerEventListenerFactory來獲取當前CacheManager所使用的CacheManagerEventListener的。CacheManagerEventListenerFactory是一個抽象類,其定義如下:
public abstract class CacheManagerEventListenerFactory { public abstract CacheManagerEventListener createCacheManagerEventListener(CacheManager cacheManager, Properties properties); }
在我們自己的CacheManagerEventListenerFactory子類中需要實現其抽象方法createCacheManagerEventListener,在生成對應的CacheManagerEventListener進行返回時我們可以使用當前的CacheManager以及在ehcache.xml文件中定義CacheManagerEventListenerFactory時指定的屬性Properties。通過CacheManagerEventListenerFactory我們可以實現為不同的CacheManager使用不同的CacheManagerEventListener。
有了CacheManagerEventListener和CacheManagerEventListenerFactory之后,我們需要在對應的ehcache.xml文件中通過cacheManagerEventListenerFactory元素來指定當前ehcache.xml文件對應的CacheManager所使用的事件監聽器工廠,每一個ehcache.xml文件中最多只能指定一個cacheManagerEventListenerFactory元素。
cacheManagerEventListenerFactory元素可以指定三個屬性:class、properties和propertySeparator。
l class屬性必須指定,表示對應的CacheManagerEventListenerFactory實現類全名。
l properties屬性可選,用來指定CacheManagerEventListenerFactory在創建CacheManagerEventListener時需要使用的屬性,里面是鍵值對的形式,多個屬性之間默認用逗號隔開。如“prop1=val1,prop2=val2”。
l propertySeparator屬性可選,用來指定properties屬性之間的分隔符。
下面給一個監聽CacheManager事件的示例。
1、實現自己的CacheManagerEventListener。
public class MyCacheManagerEventListener implements CacheManagerEventListener { private final CacheManager cacheManager; public MyCacheManagerEventListener(CacheManager cacheManager) { this.cacheManager = cacheManager; } @Override public void init() throws CacheException { System.out.println("init....."); } @Override public Status getStatus() { System.out.println("getStatus....."); returnnull; } @Override public void dispose() throws CacheException { System.out.println("dispose......"); } @Override public void notifyCacheAdded(String cacheName) { System.out.println("cacheAdded......." + cacheName); System.out.println(cacheManager.getCache(cacheName)); } @Override public void notifyCacheRemoved(String cacheName) { System.out.println("cacheRemoved......" + cacheName); } }
2、實現自己的CacheManagerEventListenerFactory,根據條件創建對應的CacheManagerEventListener。
public class MyCacheManagerEventListenerFactory extends CacheManagerEventListenerFactory { @Override public CacheManagerEventListener createCacheManagerEventListener( CacheManager cacheManager, Properties properties) { returnnew MyCacheManagerEventListener(cacheManager); } }
3、在ehcache.xml文件中通過cacheManagerEventListenerFactory元素指定當前CacheManager所使用的CacheManagerEventListenerFactory為我們自己定義的CacheManagerEventListenerFactory。
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" maxBytesLocalHeap="100M"> <diskStore path="d:\\ehcache" /> <cacheManagerEventListenerFactory class="xxx.MyCacheManagerEventListenerFactory"/> <defaultCache/> </ehcache>
針對於上述監聽器所進行的測試代碼如下所示:
@Test public void testAdd() { CacheManager cacheManager = CacheManager.create(this.getClass().getResource("/ehcache-listener.xml")); cacheManager.addCache("test1"); cacheManager.removeCache("test1"); }
2 Cache監聽器
Ehcache中定義了一個CacheEventListener接口來監聽Cache的事件。其能監聽到Cache中元素的添加、刪除、更新等。CacheEventListener中主要定義有以下方法:
public interface CacheEventListener extends Cloneable { void notifyElementRemoved(Ehcache cache, Element element) throws CacheException; void notifyElementPut(Ehcache cache, Element element) throws CacheException; void notifyElementUpdated(final Ehcache cache, final Element element) throws CacheException; void notifyElementExpired(final Ehcache cache, final Element element); void notifyElementEvicted(final Ehcache cache, final Element element); void notifyRemoveAll(final Ehcache cache); public Object clone() throws CloneNotSupportedException; void dispose(); }
l notifyElementRemoved方法會在往Cache中移除單個元素時被調用,即在調用Cache的remove方法之后被調用。
l notifyElementPut方法會在往Cache中添加元素時被調用。調用Cache的put方法添加元素時會被阻塞,直到對應的notifyElementPut方法返回之后。
l notifyElementUpdated方法,當往Cache中put一個已經存在的元素時就會觸發CacheEventListener的notifyElementUpdated方法,此時put操作也會處於阻塞狀態,直到notifyElementUpdated方法執行完畢。
l notifyElementExpired方法,當Ehcache檢測到Cache中有元素已經過期的時候將調用notifyElementExpired方法。
l notifyElementEvicted方法將會在元素被驅除的時候調用。
l notifyRemoveAll方法將在調用Cache的removeAll方法之后被調用。
dispose方法用於釋放資源。
那我們在實現自己的CacheEventListener時就需要實現上述所有的方法。Ehcache為我們提供了一個默認的空實現CacheEventListenerAdapter,我們可以在實際應用中繼承CacheEventListenerAdapter,然后重寫其中的某些方法,以簡化我們對CacheEventListener的實現。
跟CacheManagerEventListener一樣,CacheEventListener不能單獨起作用,它需要通過當前Cache相關聯的CacheEventListenerFactory來構建一個當前Cache使用的CacheEventListener。CacheEventListenerFactory是一個抽象類,其中只定義了一個createCacheEventListener方法,該方法接收一個Properties對象作為參數。
在ehcahce.xml文件中通過cache元素下的子元素cacheEventListenerFactory可以指定當前Cache所使用的CacheEventListenerFactory。其可以指定四個屬性:
l class:指定當前CacheEventListenerFactory對應的Java類全名稱。
l properties:指定在構建CacheEventListenerFactory時需傳入的屬性鍵值對,多個屬性之間默認用逗號分開,如:“prop1=value1,prop2=value2”。
l propertySeparator:指定properties中多個屬性之間的分隔符。
l listenFor:表示在集群環境下可以監聽到的Cache事件的范圍,可選值有local、remote和all。local代表只監聽本節點的Cache事件,remote代表只監聽其他節點的Cache事件,all代表監聽所有的Cache事件。默認是all。
與CacheManagerEventListenerFactory不同的是一個Cache可以定義多個CacheEventListenerFactory。
下面來看一個使用Cache監聽器的例子。
1、實現一個CacheEventListener。
public class MyCacheEventListener implements CacheEventListener { @Override public void notifyElementRemoved(Ehcache cache, Element element) throws CacheException { System.out.println("removed"); } @Override public void notifyElementPut(Ehcache cache, Element element) throws CacheException { System.out.println("put"); } @Override public void notifyElementUpdated(Ehcache cache, Element element) throws CacheException { System.out.println("updated"); } @Override public void notifyElementExpired(Ehcache cache, Element element) { System.out.println("expired"); } @Override public void notifyElementEvicted(Ehcache cache, Element element) { System.out.println("evicted"); } @Override public void notifyRemoveAll(Ehcache cache) { System.out.println("removeAll"); } @Override public void dispose() { } public Object clone() throws CloneNotSupportedException { thrownew CloneNotSupportedException(); } }
2、實現抽象工廠類CacheEventListenerFactory來生產前面已經定義好的CacheEventListener。
public class MyCacheEventListenerFactory extends CacheEventListenerFactory { @Override public CacheEventListener createCacheEventListener(Properties properties) { returnnew MyCacheEventListener(); } }
3、在ehcache.xml文件中通過cache元素的子元素cacheEventListenerFactory來指定當前Cache使用的CacheEventListenerFactory。
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" maxBytesLocalHeap="100M"> <diskStore path="d:\\ehcache" /> <cache name="test"> <cacheEventListenerFactory class="xxx.xxx.MyCacheEventListenerFactory"/> </cache> <defaultCache/> </ehcache>
經過以上三步我們就完成了對Cache事件的監聽。
(注:本文是基於ehcache2.8.1所寫)