1. 类图
2. 概述
Ehcache的类层次模型主要为三层,最上层的是CacheManager,他是操作Ehcache的入口。我们可以通过CacheManager.getInstance()获得一个单子的CacheManger,或者通过CacheManger的构造函数创建一个新的CacheManger。每个CacheManager都管理着多个Cache。而每个Cache都以一种类Hash的方式,关联着多个Element。而Element则是我们用于存放要缓存内容的地方。
3. 配置文件
a) 参考:http://ehcache.sourceforge.net/documentation/configuration.html
b) 例子:
<ehcache xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
xsi:noNamespaceSchemaLocation="ehcache.xsd">
<defaultCache maxElementsInMemory="2" eternal="false" timeToIdleSeconds="1"
timeToLiveSeconds="1" overflowToDisk="false" memoryStoreEvictionPolicy="LRU"/>
<cache name="sampleCache1" maxElementsInMemory="2" eternal="false"
overflowToDisk="false" timeToIdleSeconds="1" timeToLiveSeconds="1"
memoryStoreEvictionPolicy="LRU"/>
</ehcache>
注:在ehcache的配置文件里面必须配置defaultCache。每个<cache>标签定义一个新的cache,属性的含义基本上可以从名字上得到,详细的说明可以参考上面的链接。
4. 事例程序:
a) 例子:
public class Test {
public static void main(String[] args) throws Exception {
CacheManager manager = new CacheManager("ehcache.xml");
Cache cache = manager.getCache("sampleCache1");
for (int i = 0; i < 5; i++) {
Element e = new Element("key" + i, "value" + i);
cache.put(e);
}
List<String> keys = cache.getKeys();
for (String key : keys) {
System.out.println(key + "," + cache.get(key));
}
}
}
注:程序的流程也是比较明晰的,首先是获取一个CacheManager,这是使用Ehcache的入口,然后通过名字获取某个Cache,然后就可以对Cache存取Element。Cache使用类Hash的方式来管理Element。
5. 事件处理
a) 说明:可以为CacheManager添加事件监听,当对CacheManager增删Cache时,事件处理器将会得到通知。要配置事件处理,需要通过ehcache的配置文件来完成。
b) 配置文件:
<ehcache>
<cacheManagerEventListenerFactory class="ehcache.CMELF"/>
</ehcache>
注:通过<cacheManagerEventListenerFactory>来注册事件处理器的工厂类。
c) 代码:
public class CMELF extends CacheManagerEventListenerFactory {
@Override
public CacheManagerEventListener createCacheManagerEventListener(
Properties properties) {
return new CMEL();
}
}
class CMEL implements CacheManagerEventListener {
public void dispose() throws CacheException {}
public Status getStatus() {return null;}
public void init() throws CacheException {}
public void notifyCacheAdded(String cacheName) {
System.out.println("Cache [" + cacheName + "] Added");
}
public void notifyCacheRemoved(String cacheName) {
System.out.println("Cache [" + cacheName + "] Deleted");
}
}
注:这个代码分为两部分,首先是一个工厂类,用于创建事件处理器事例,工厂类负责还需要管理并发之类的问题。
6. 事件处理
a) 说明:可以为Cache添加事件监听,当对Cache增删Element时,事件处理器将会得到通知。要配置事件处理,需要通过ehcache的配置文件来完成。
b) 配置文件:
<ehcache>
<cache name="sampleCache1">
<cacheEventListenerFactory class="ehcache.CELF"/>
</cache>
</ehcache>
c) 代码:
public class CELF extends CacheEventListenerFactory {
@Override
public CacheEventListener createCacheEventListener(Properties properties) {
return new CEL();
}
}
class CEL implements CacheEventListener {
public void dispose() {}
public void notifyElementEvicted(Ehcache cache, Element element) {}
public void notifyElementExpired(Ehcache cache, Element element) {}
public void notifyElementPut(Ehcache cache, Element element)
throws CacheException {
System.out.println(element.getKey() + " was added.");
}
public void notifyElementRemoved(Ehcache cache, Element element)
throws CacheException {
System.out.println(element.getKey() + " was removed.");
}
public void notifyElementUpdated(Ehcache cache, Element element)
throws CacheException {}
public void notifyRemoveAll(Ehcache cache) {}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
注:这里的代码与之前的类似,由此可见Ehcache的事件处理采用的是一种类plugin方式,也就是说,事件处理的添加是以不修改源代码为前提的。
7. 在Hibernate中使用Ehcache
a) 说明:要在hibernate中使用Ehcache,需要修改3个文件。
b) ehcache.xml
<ehcache>
<defaultCache/>
<cache name="objCache"/>
</ehcache>
注:这里我们创建了一个名为“objCache”的缓存。
c) hibernate.cfg.xml
<hibernate-configuration>
<session-factory>
<property name="hibernate.cache.provider_class">
org.hibernate.cache.EhCacheProvider
</property>
<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.provider_configuration_file_resource_path">
ehcache.xml
</property>
<property name="hibernate.generate_statistics">true</property>
</session-factory>
</hibernate-configuration>
注:这里我们声明了要使用的缓存类型为Ehcache,并指定了配置文件的地址。
d) mapping
<hibernate-mapping>
<class …>
<cache usage="read-write" region="objCache"/>
<id name="id" column="id" type="java.lang.Integer">
<generator class="native"></generator>
</id>
<property name="name" type="string"></property>
<property name="age" type="int"></property>
</class>
</hibernate-mapping>
注:这里,我们usage指名了什么样的操作需要使用cache,而region指明了在那个cache上进行操作,如果不声明region,则在defaultCache上操作。