所谓缓存,就是将程序或系统经常要调用的对象存在内存中,以便其使用时可以快速调用,不必再去创建新的重复的实例。这样做可以减少系统开销,提高系统效率。
缓存主要可分为二大类:
一、通过文件缓存,顾名思义文件缓存是指把数据存储在磁盘上,不管你是以XML格式,序列化文件DAT格式还是其它文件格式;
二、内存缓存,也就是实现一个类中静态Map,对这个Map进行常规的增删查.
一、EhCache缓存系统简介
EhCache 是一个纯 Java 的进程内缓存框架,具有快速、精干等特点,是 Hibernate 中默认的 CacheProvider。
EhCache 应用架构图,下图是 EhCache 在应用程序中的位置:
EhCache 的主要特性有:
1. 快速、精干; 2. 简单; 3. 多种缓存策略; 4. 缓存数据有两级:内存和磁盘,因此无需担心容量问题; 5. 缓存数据会在虚拟机重启的过程中写入磁盘; 6. 可以通过 RMI、可插入 API 等方式进行分布式缓存; 7. 具有缓存和缓存管理器的侦听接口; 8. 支持多缓存管理器实例,以及一个实例的多个缓存区域; 9. 提供 Hibernate 的缓存实现;
二、maven添加Ehcache核心包
在pom.xml配置文件里,添加
<!--ehcache 相关包 --> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> <version>2.7.5</version> </dependency> <dependency> <groupId>com.googlecode.ehcache-spring-annotations</groupId> <artifactId>ehcache-spring-annotations</artifactId> <version>1.2.0</version> </dependency>
三、添加配置文件
在资源文件夹下(通常是src/main/resources/META-INF) 添加 applicationContext-ehcache.xml、ehcache.xml
1、applicationContext-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:c="http://www.springframework.org/schema/c" xmlns:cache="http://www.springframework.org/schema/cache" xmlns:context="http://www.springframework.org/schema/context" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:lang="http://www.springframework.org/schema/lang" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p" xmlns:task="http://www.springframework.org/schema/task" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util" 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/cache http://www.springframework.org/schema/cache/spring-cache.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> <!-- 开启spring缓存 --> <cache:annotation-driven cache-manager="cacheManager" /> <bean id="cacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"> <property name="configLocation" value="classpath:META-INF/ehcache.xml"/> </bean> <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"> <property name="cacheManager" ref="cacheManagerFactory"/> </bean> </beans>
这里是开启spring缓存
2、ehcache.xml内容如下:
<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true" monitoring="autodetect" dynamicConfig="true"> <diskStore path="${java.io.tmpdir}/${system.project_name}/cache" /> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" maxElementsOnDisk="10000000" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" /> <cache name="baseCache" maxElementsInMemory="200" maxElementsOnDisk="1000" eternal="false" overflowToDisk="true" diskSpoolBufferSizeMB="20" timeToIdleSeconds="300" timeToLiveSeconds="600" memoryStoreEvictionPolicy="LFU" /> </ehcache>
这里是添加缓存策略
说明:
1、java.io.tmpdir 所指地址:
操作系统不同 这个系统属性所表示的目录也不同 On Windows: java.io.tmpdir:[C:\DOCUME~1\joshua\LOCALS~1\Temp\] On Solaris: java.io.tmpdir:[/var/tmp/] On Linux: java.io.tmpdir: [/tmp] On Mac OS X: java.io.tmpdir: [/tmp] The default temporary-file directory is specified by the system property java.io.tmpdir. On UNIX systems the default value of this property is typically "/tmp" or "/var/tmp"; on Microsoft Windows systems it is typically "c:\temp". A different value may be given to this system property when the Java virtual machine is invoked, but programmatic changes to this property are not guaranteed to have any effect upon the the temporary directory used by this method. To specify the java.io.tmpdir System property, you can invoke the JVM as follows: java -Djava.io.tmpdir=/path/to/tmpdir By default this value should come from the TMP environment variable on Windows systems
2、数据含义
name:Cache的唯一标识 maxElementsInMemory:内存中最大缓存对象数 maxElementsOnDisk:磁盘中最大缓存对象数,若是0表示无穷大 eternal:Element是否永久有效,一但设置了,timeout将不起作用 overflowToDisk:配置此属性,当内存中Element数量达到maxElementsInMemory时,Ehcache将会Element写到磁盘中 timeToIdleSeconds:设置Element在失效前的允许闲置时间。仅当element不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大 timeToLiveSeconds:设置Element在失效前允许存活时间。最大时间介于创建时间和失效时间之间。仅当element不是永久有效时使用,默认是0.,也就是element存活时间无穷大 diskPersistent:是否缓存虚拟机重启期数据 diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒 diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区 memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出) 或是LFU(较少使用)
四、DAO层做配置
import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.Cacheable; ..... @TriggersRemove(cacheName="baseCache",removeAll=true) public Entity save(Entity entity) throws CrudException { return entity; } @TriggersRemove(cacheName="baseCache",removeAll=true) public Entity update(Entity entity) throws CrudException { return entity; } @TriggersRemove(cacheName="baseCache",removeAll=true) public void del(Entity entity) throws CrudException { } @Cacheable(value="baseCache", key = "‘findAll‘") public List<Entity> findAll() throws SearchException { return list; }
@Cacheable(value="baseCache", key = "‘findAll‘")
这个注解就是做到缓存数据,cacheName对应ehcache.xml 中配置
@TriggersRemove(cacheName="baseCache",removeAll=true)
这个注解的作用就是当数据发生变化的时候清除缓存,做到数据同步
扩展:@Cacheable可以指定三个属性,value、key和condition。
1、@Cacheable("cache1")、@Cacheable({"cache1", "cache2"})//Cache是发生在cache1和cache2上的
value属性是必须指定的,其表示当前方法的返回值是会被缓存在哪个Cache上的,对应Cache的名称。其可以是一个Cache也可以是多个Cache,当需要指定多个Cache时其是一个数组。
2、@Cacheable(value="users", key="#user.id")、@Cacheable(value="users", key="#p0")
key属性是用来指定Spring缓存方法的返回结果时对应的key的。该属性支持SpringEL表达式。当我们没有指定该属性时,Spring将使用默认策略生成key。我们这里先来看看自定义策略,自定义策略是指我们可以通过Spring的EL表达式来指定我们的key。这里的EL表达式可以使用方法参数及它们对应的属性
3、@Cacheable(value={"users"}, key="#user.id", condition="#user.id%2==0")
有的时候我们可能并不希望缓存一个方法所有的返回结果。通过condition属性可以实现这一功能。condition属性默认为空,表示将缓存所有的调用情形。其值是通过SpringEL表达式来指定的,当为true时表示进行缓存处理;当为false时表示不进行缓存处理,即每次调用该方法时该方法都会执行一次。以上下示例表示只有当user的id为偶数时才会进行缓存。
4、@CachePut("users")
在支持Spring Cache的环境下,对于使用@Cacheable标注的方法,Spring在每次执行前都会检查Cache中是否存在相同key的缓存元素,如果存在就不再执行该方法,而是直接从缓存中获取结果进行返回,否则才会执行并将返回结果存入指定的缓存中。@CachePut也可以声明一个方法支持缓存功能。与@Cacheable不同的是使用@CachePut标注的方法在执行前不会去检查缓存中是否存在之前执行过的结果,而是每次都会执行该方法,并将执行结果以键值对的形式存入指定的缓存中。
@CachePut也可以标注在类上和方法上。使用@CachePut时我们可以指定的属性跟@Cacheable是一样的。
5、@CacheEvict(value="users", allEntries=true)
allEntries是boolean类型,表示是否需要清除缓存中的所有元素。默认为false,表示不需要。当指定了allEntries为true时,Spring Cache将忽略指定的key。有的时候我们需要Cache一下清除所有的元素,这比一个一个清除元素更有效率。
6、@CacheEvict(value="users", beforeInvocation=true)
清除操作默认是在对应方法成功执行之后触发的,即方法如果因为抛出异常而未能成功返回时也不会触发清除操作。使用beforeInvocation可以改变触发清除操作的时间,当我们指定该属性值为true时,Spring会在调用该方法之前清除缓存中的指定元素。
7、@Caching(cacheable = @Cacheable("users"), evict = { @CacheEvict("cache2"),
@CacheEvict(value = "cache3", allEntries = true) })
public User find(Integer id) {
return null;
}
@Caching注解可以让我们在一个方法或者类上同时指定多个Spring Cache相关的注解。其拥有三个属性:cacheable、put和evict,分别用于指定@Cacheable、@CachePut和@CacheEvict。
如何知道有没生效:查看sql执行日志
参考:
http://www.blogjava.net/zzzlyr/articles/343234.html
http://blog.goyello.com/2010/07/29/quick-start-with-ehcache-annotations-for-spring/
http://haohaoxuexi.iteye.com/blog/2123030