轉載請注明出處哈: http://carlosfu.iteye.com/blog/2237511
一、依賴
1. ehcache依賴
<ehcache.version>2.6.11</ehcache.version>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>${ehcache.version}</version>
</dependency>
2. ehcache依賴樹: mvn dependency:tree
[INFO] \- net.sf.ehcache:ehcache-core:jar:2.6.11:compile
[INFO] \- org.slf4j:slf4j-api:jar:1.7.5:compile
3. 由于slf4j-api是日志接口,加入具體實作logback(log4j也可以)
<logback.version>1.0.13</logback.version>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
4. 為了友善單元測試,引入junit
<junit.version>4.11</junit.version>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
最終pom:
<properties>
<ehcache.version>2.6.11</ehcache.version>
<logback.version>1.0.13</logback.version>
<junit.version>4.11</junit.version>
</properties>
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>${ehcache.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
二、ehcache配置
注意:如果不添加,會使用ehcache-core-2.6.11.jar下的ehcache-failsafe.xml作為預設配置
一般來說需要把ehcache.xml放到classpath下:我們使用極簡配置
<?xml version="1.0" encoding="UTF-8" ?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
<cache name="firstEhcache" maxElementsInMemory="10000">
</cache>
</ehcache>
三、logback配置
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="5 seconds">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
四、單元測試
1. 一個實體類:
package com.sohu.tv.ehcache.first;
import java.util.Date;
/**
* 俱樂部
*
* @author leifu
* @Date 2015年7月28日
* @Time 下午1:43:53
*/
public class Club {
/**
* 俱樂部id
*/
private int id;
/**
* 俱樂部名
*/
private String clubName;
/**
* 俱樂部描述
*/
private String clubInfo;
/**
* 建立日期
*/
private Date createDate;
/**
* 排名
*/
private int rank;
public Club(int id, String clubName, String clubInfo, Date createDate, int rank) {
super();
this.id = id;
this.clubName = clubName;
this.clubInfo = clubInfo;
this.createDate = createDate;
this.rank = rank;
}
public Club() {
super();
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getClubName() {
return clubName;
}
public void setClubName(String clubName) {
this.clubName = clubName;
}
public String getClubInfo() {
return clubInfo;
}
public void setClubInfo(String clubInfo) {
this.clubInfo = clubInfo;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public int getRank() {
return rank;
}
public void setRank(int rank) {
this.rank = rank;
}
@Override
public String toString() {
return "Club [id=" + id + ", clubName=" + clubName + ", clubInfo=" + clubInfo + ", createDate=" + createDate
+ ", rank=" + rank + "]";
}
}
2. 單元測試:
package com.sohu.tv.ehcache.first;
import java.util.Date;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
/**
* 第一個ehcache測試
*
* @author leifu
* @Date 2015年8月12日
* @Time 上午10:14:13
*/
public class FirstEhcacheTest {
private static Logger logger = LoggerFactory.getLogger(FirstEhcacheTest.class);
private static Cache cache;
@BeforeClass
public static void setUp() {
CacheManager cacheManager = CacheManager.create(FirstEhcacheTest.class.getClassLoader().getResourceAsStream("ehcache.xml"));
// 列印cacheManager管理的cache
String[] cacheNameArr = cacheManager.getCacheNames();
for (String cacheName : cacheNameArr) {
logger.info("cacheName: {}", cacheName);
}
cache = cacheManager.getCache("firstEhcache");
}
@Test
public void testCRUD() {
logger.info("At start, ehcache object size: {}", cache.getSize());
// 唯一key
String key = "football:club:1";
Club club = new Club(1, "AC", "AC米蘭", new Date(), 1);
// 增
Element element = new Element(key, club);
cache.put(element);
logger.info("after add ehcache object size: {}", cache.getSize());
// 查
Element elementResult = cache.get(key);
Club clubResult = (Club) elementResult.getObjectValue();
logger.info("get key {} value is {}", key, clubResult.toString());
// 修改
club.setRank(8888);
cache.put(element);
logger.info("after set ehcache object size: {}", cache.getSize());
// 再查
Element elementResultAgain = cache.get(key);
Club clubResultAgain = (Club) elementResultAgain.getObjectValue();
logger.info("get key {} again value is {}", key, clubResultAgain.toString());
// 删
boolean removeResult = cache.remove(key);
logger.info("remove result is {}, after remove ehcache object size: {}", removeResult, cache.getSize());
// 增加一條,觀察下次啟動
cache.put(element);
logger.info("At final, ehcache object size: " + cache.getSize());
// 生産環境不要使用,影響性能
logger.info("At final, ehcache memory size: " + cache.calculateInMemorySize());
}
}
五、輸出:
10:43:11.405 [main] INFO c.s.t.ehcache.first.FirstEhcacheTest - cacheName: firstEhcache
10:43:11.410 [main] INFO c.s.t.ehcache.first.FirstEhcacheTest - At start, ehcache object size: 0
10:43:11.413 [main] INFO c.s.t.ehcache.first.FirstEhcacheTest - after add ehcache object size: 1
10:43:11.416 [main] INFO c.s.t.ehcache.first.FirstEhcacheTest - get key football:club:1 value is Club [id=1, clubName=AC, clubInfo=AC米蘭, createDate=Wed Aug 12 10:43:11 CST 2015, rank=1]
10:43:11.416 [main] INFO c.s.t.ehcache.first.FirstEhcacheTest - after set ehcache object size: 1
10:43:11.417 [main] INFO c.s.t.ehcache.first.FirstEhcacheTest - get key football:club:1 again value is Club [id=1, clubName=AC, clubInfo=AC米蘭, createDate=Wed Aug 12 10:43:11 CST 2015, rank=8888]
10:43:11.417 [main] INFO c.s.t.ehcache.first.FirstEhcacheTest - remove result is true, after remove ehcache object size: 0
10:43:11.417 [main] INFO c.s.t.ehcache.first.FirstEhcacheTest - At final, ehcache object size: 1
10:43:11.418 [main] INFO c.s.t.ehcache.first.FirstEhcacheTest - At final, ehcache memory size: 1
六、結論、注意、猜想:
1. 如果沒有配置diskStore作為持久化資料源,每次啟動時候ehcache都是空的(因為ehcache是程序内緩存,會伴随着JVM的結束而消失)
2. ehcache接口中 put代表了add和set。
3. 官方文檔中說:cache.calculateInMemorySize()這個方法不要在生産環境中使用,會影響性能。
4. Ehcache的增删改查API使用十分簡單。
Ehcache優化配置相當多:各個層級資料容量大小、key過期政策算法、overFlow政策、序列化等等。