一、ehcache简介
EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认的CacheProvider。
Ehcache是一个用Java实现的使用简单,高速,实现线程安全的缓存管理类库,ehcache提供了用内存,磁盘文件存储,以及分布式存储方式等多种灵活的cache管理方案。同时ehcache作为开放源代码项目,采用限制比较宽松的Apache License V2.0作为授权方式,被广泛地用于Hibernate, Spring,Cocoon等其他开源系统。Ehcache 从 Hibernate 发展而来,逐渐涵盖了 Cahce 界的全部功能,是目前发展势头最好的一个项目。具有快速,简单,低消耗,依赖性小,扩展性强,支持对象或序列化缓存,支持缓存或元素的失效,提供 LRU、LFU 和 FIFO 缓存策略,支持内存缓存和磁盘缓存,分布式缓存机制等等特点。
二、ehcache的主要特征
- 快速;
- 简单;
- 多种缓存策略;
- 缓存数据有两级:内存和磁盘,因此无需担心容量问题;
- 缓存数据会在虚拟机重启的过程中写入磁盘;
- 可以通过 RMI、可插入 API 等方式进行分布式缓存;
- 具有缓存和缓存管理器的侦听接口;
- 支持多缓存管理器实例,以及一个实例的多个缓存区域;
- 提供 Hibernate 的缓存实现;
由于 EhCache 是进程中的缓存系统,一旦将应用部署在集群环境中,每一个节点维护各自的缓存数据,当某个节点对缓存数据进行更新,这些更新的数据无法在其它节点中共享,这不仅会降低节点运行的效率,而且会导致数据不同步的情况发生。
三、Ehcache的架构设计图
说明
CacheManager:是缓存管理器,可以通过单例或者多例的方式创建,也是Ehcache的入口类。
Cache:每个CacheManager可以管理多个Cache,每个Cache可以采用hash的方式管理多个Element。
Element:用于存放真正缓存内容的。
四、SSH整合ehcache
1.pom文件,除去spring核心的jar包需要添加外,还要添加以下jar包依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.10.2</version>
</dependency>
2.classpath下添加ehcache.xml,可以配置多个cache对象【defaultCache、cache1、cache2】
<ehcache>
<diskStore path="data/ehcache"/>
<defaultCache
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false"/>
<cache name="cache1"
maxElementsOnDisk="20000"
maxElementsInMemory="2000"
eternal="true"
overflowToDisk="true"
diskPersistent="true"/>
<cache name="cache2"
maxElementsOnDisk="20000"
maxElementsInMemory="2000"
eternal="true"
overflowToDisk="true"
diskPersistent="true"/>
</ehcache>
3.添加ehcache配置的文件spring-ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
<!-- Spring提供的基于Ehcache实现的缓存管理器 -->
<bean id="ehCacheManager"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:/ehcache.xml" />
<property name="shared" value="true" />
</bean>
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
<property name="cacheManager" ref="ehCacheManager" />
</bean>
<!-- 启用缓存注解功能(请将其配置在Spring主配置文件中) -->
<cache:annotation-driven cache-manager="cacheManager" />
</beans>
4.代码举例【可以缓存一个对象或集合】
package com.ctc.ServiceImpl;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import com.ctc.Dao.UserDao;
import com.ctc.Model.User;
import com.ctc.Service.UserService;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;
@Service("userServiceImpl")
public class UserServiceImpl implements UserService {
@Resource
UserDao userDaoImpl;
private static final CacheManager cacheManager = CacheManager.create();
@Override
public User showUser(int id) {
Ehcache cache = cacheManager.getEhcache("cache1");//获取指定cache对象
User user = null;
Element element = cache.get(id);//用户ID作为缓存的key
if (element != null) {
//走缓存
user = (User) element.getObjectValue();
} else {
//查询数据库
user = userDaoImpl.load(id);
cache.put(new Element(id, user));//放的是Element
}
return user;
}
}
5.注解实现
package com.ctc.ServiceImpl;
import javax.annotation.Resource;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import com.ctc.Dao.UserDao;
import com.ctc.Model.User;
import com.ctc.Service.UserService;
@Service("userServiceImpl")
public class UserServiceImpl implements UserService {
@Resource
UserDao userDaoImpl;
//将查询到的数据缓存到cache1中,并使用方法名称加上参数中的id作为缓存的key
@Override
@Cacheable(value="cache1", key="'showUser'+#id")
public User showUser(int id) {
User user =null;
user = userDaoImpl.load(id);
System.out.println("数据库中查到此用户号[" + id + "]对应的用户名为[" + user.getUserName()+ "]");
return user;
}
//通常更新操作只需刷新缓存中的某个值,所以为了准确的清除特定的缓存,故定义了这个唯一的key,从而不会影响其它缓存值
@Override
@CacheEvict(value="cache1", key="'showUser'+#id")
public void updateUser(int id) {
User user = showUser(id);
this.userDaoImpl.update(user);
System.out.println("移除缓存中此用户号[" + id + "]对应的用户名[" + user.getUserName() + "]的缓存");
}
//allEntries为true表示清除value中的全部缓存,默认为false
@CacheEvict(value="cache1", allEntries=true)
public void removeAll(){
System.out.println("移除缓存中的所有数据");
}
}