RemovalNotification
实现Map.Entry接口
getCause()获取RemovalCause
1.COLLECTED: key或value被垃圾回收;
2.EXPIRED:已过期;
3.EXPLICIT:手动移除;
4.REPLACED:被替换;
5.SIZE:超过了最大限制数量。
package bbejeck.guava.chapter6.cache;/*** User: Bill Bejeck* Date: 4/22/13* Time: 9:37 PM*/import com.google.common.cache.RemovalCause;
import com.google.common.cache.RemovalListener;public abstract class BaseRemovalListener<K, V> implements RemovalListener<K, V> {protected RemovalCause removalCause;protected K removedKey;protected V removedValue;public RemovalCause getRemovalCause() {return removalCause;}public K getRemovedKey() {return removedKey;}public V getRemovedValue() {return removedValue;}
}
package bbejeck.guava.chapter6.cache;import bbejeck.guava.common.model.TradeAccount;
import com.google.common.cache.RemovalListener;
import com.google.common.cache.RemovalNotification;/*** User: Bill Bejeck* Date: 4/20/13* Time: 11:49 PM*/
public class TradeAccountRemovalListener extends BaseRemovalListener<String, TradeAccount> {public void onRemoval(RemovalNotification<String, TradeAccount> notification) {this.removalCause = notification.getCause();this.removedKey = notification.getKey();this.removedValue = notification.getValue();}
}
package bbejeck.guava.chapter6.cache;import bbejeck.guava.common.model.Book;
import bbejeck.guava.common.model.TradeAccount;
import bbejeck.guava.common.service.BookServiceImpl;
import bbejeck.guava.common.service.TradeAccountService;
import com.google.common.base.Ticker;
import com.google.common.cache.*;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;import java.util.concurrent.TimeUnit;import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;/*** User: Bill Bejeck* Date: 4/20/13* Time: 10:17 PM*/
public class RemovalListenerTest {private static TradeAccountService tradeAccountService;private static BookServiceImpl bookService;@BeforeClasspublic static void startUpBeforeAll() {bookService = new BookServiceImpl();tradeAccountService = new TradeAccountService();}@AfterClasspublic static void tearDownAfterAll() throws Exception {bookService.shutdown();tradeAccountService.shutdown();}@Testpublic void testLoadingCacheExpireAfterWrite() throws Exception {TradeAccountRemovalListener removalListener = new TradeAccountRemovalListener();LoadingCache<String, TradeAccount> tradeAccountCache = CacheBuilder.newBuilder().expireAfterWrite(5L, TimeUnit.MILLISECONDS).maximumSize(5000L).removalListener(removalListener).ticker(Ticker.systemTicker()).build(new CacheLoader<String, TradeAccount>() {@Overridepublic TradeAccount load(String key) throws Exception {return tradeAccountService.getTradeAccountById(key);}});//223,"Rogers, Jim",250000.12TradeAccount tradeAccount = tradeAccountCache.get("223");assertThat(tradeAccount.getBalance(), is(250000.12));Thread.sleep(10L);tradeAccountCache.get("223");assertThat(removalListener.getRemovalCause(), is(RemovalCause.EXPIRED));assertThat(removalListener.getRemovedValue(), is(tradeAccount));}@Testpublic void testRemovalAfterLastAccessed() throws Exception {BookRemovalListener bookRemovalListener = new BookRemovalListener();LoadingCache<String, Book> bookCache = CacheBuilder.newBuilder().expireAfterAccess(10, TimeUnit.MILLISECONDS).softValues().recordStats().removalListener(bookRemovalListener).build(new CacheLoader<String, Book>() {@Overridepublic Book load(String key) throws Exception {return bookService.findBookByIsbn(key);}});Book book = bookCache.get("ISBN-234567");assertThat(book.getAuthor(), is("Vandeley, Art"));assertThat(book.getIsbn(), is("ISBN-234567"));Thread.sleep(20);//Need to call again to force evictionBook bookII = bookCache.get("ISBN-234567");assertThat(bookII.getAuthor(), is("Vandeley, Art"));assertThat(bookII.getIsbn(), is("ISBN-234567"));CacheStats cacheStats = bookCache.stats();assertThat(cacheStats.evictionCount(),is(1l));assertThat(bookRemovalListener.getRemovalCause(), is(RemovalCause.EXPIRED));assertThat(bookRemovalListener.getRemovedKey(), is("ISBN-234567"));assertThat(bookRemovalListener.getRemovedValue(), is(book));}@Testpublic void testInvalidateBadValue() throws Exception {BookRemovalListener bookRemovalListener = new BookRemovalListener();LoadingCache<String, Book> bookCache = CacheBuilder.newBuilder().expireAfterAccess(10, TimeUnit.HOURS).softValues().recordStats().removalListener(bookRemovalListener).build(new CacheLoader<String, Book>() {@Overridepublic Book load(String key) throws Exception {return bookService.findBookByIsbn(key);}});Book book = bookCache.get("ISBN-234567");assertThat(book.getTitle(), is("Be an Architect"));bookCache.invalidate("ISBN-234567");assertThat(bookRemovalListener.getRemovalCause(), is(RemovalCause.EXPLICIT));assertThat(bookRemovalListener.getRemovedValue().getTitle(), is("Be an Architect"));}@Testpublic void testRefreshingCacheValues() throws Exception {TradeAccountRemovalListener removalListener = new TradeAccountRemovalListener();LoadingCache<String, TradeAccount> tradeAccountCache = CacheBuilder.newBuilder().concurrencyLevel(10).refreshAfterWrite(5L, TimeUnit.MILLISECONDS).removalListener(removalListener).ticker(Ticker.systemTicker()).recordStats().build(new CacheLoader<String, TradeAccount>() {@Overridepublic TradeAccount load(String key) throws Exception {return tradeAccountService.getTradeAccountById(key);}});//223,"Rogers, Jim",250000.12TradeAccount tradeAccount = tradeAccountCache.get("223");assertThat(tradeAccount.getBalance(), is(250000.12));Thread.sleep(10L);tradeAccountCache.get("223");CacheStats stats = tradeAccountCache.stats();assertThat(stats.loadSuccessCount(),is(2l));assertThat(removalListener.getRemovalCause(), is(RemovalCause.REPLACED));assertThat(removalListener.getRemovedValue(), is(tradeAccount));}}