Spring的缓存

来源:互联网 发布:淘宝网已买到的宝贝 编辑:程序博客网 时间:2024/05/21 00:20

1.Spring 缓存介绍

1.1 Spring 缓存简介

Spring 提供了对缓存功能的抽象:即允许绑定不同的缓存解决方案(如Ehcache),但本身不直接提供缓存功能的实现。它支持注解方式使用缓存,非常方便。

1.2 缓存管理器

Spring 3.1内置了五个缓存管理器实现,如下所示:
- SimpleCacheManager
- NoOpCacheManager
- ConcurrentMapCacheManager
- CompositeCacheManager
- EhCacheCacheManager

Spring 3.2引入了另外一个缓存管理器,这个管理器可以用在基于JCach e(JSR-107)的缓存提供商之中。除了核心的Spring框架,Spring Data又提供了两个缓存管理器:
- RedisCacheManager(来自于Spring Data Redis项目)
- GemfireCacheManager(来自于Spring Data GemFire项目)


2. Spring 缓存使用

2.1 注解方式

@Cacheable

说明: 表明Spring在调用方法之前,首先应该在缓存中查找方法的返回值。如果这个值能够找到,就会返回缓存的值。否则的话,这个方法就会被调用,返回值会放到缓存之中

@CachePut

说明: 表明Spring应该将方法的返回值放到缓存中。在方法的调用前并不会检查缓存,方法始终都会被调用

参数 作用 例 (@Cacheable和@CachePut) value 缓存的名称,在spring 配置文件中定义,必须指定至少一个 @Cacheable(value=”mycache”) @Cacheable(value={”cache1”,”cache2”} key 缓存的key,可以为空,如果指定要按照SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 @Cacheable(value=”testcache”,key=”#userName”) condition 缓存的条件,可以为空,使用SpEL编写,返回true或者false只有为true才进行缓存 @Cacheable(value=”testcache”,condition=”#userName.length()>2”) unless SpEL表达式,可以为空,如果得到的值是true的话,返回值不会放到缓存之中

@CacheEvict

说明: 表明Spring应该在缓存中清除一个或多个条目

参数 作用 例 @CacheEvict) value 缓存的名称,在spring 配置文件中定义,必须指定至少一个 @CacheEvict(value=”mycache”) @Cacheable(value={”cache1”,”cache2”} key 缓存的key,可以为空,如果指定要按照SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合 @CachEvict(value=”testcache”,key=”#userName”) condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才清空缓存 @CachEvict(value=”testcache”,condition=”#userName.length()>2”) allEntries 是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存 @CachEvict(value=”testcache”,allEntries=true) beforeInvocation 是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存 @CachEvict(value=”testcache”,beforeInvocation=true)

@Caching

说明: 使用同一个缓存注解多次修饰一个方法.
例:
这里写图片描述

@CacheConfig

说明: 与前面的缓存注解不同,这是一个类级别的注解。如果类的所有操作都是缓存操作,你可以使用@CacheConfig来指定类,省去一些配置。
例:
这里写图片描述

SpEL扩展

Spring提供了多个用来定义缓存规则的SpEL扩展

属性名称 描述 表达式 methodName 当前方法名 `#root.methodName method 当前方法 `#root.method.name target 当前被调用的对象 `#root.target targetClass 当前被调用的对象的class `#root.targetClass args 当前方法参数组成的数组 `#root.args[0] caches 当前被调用的方法使用的Cache `#root.caches[0].name 方法调用的返回值(不能用在@Cacheable注解上) `#result 任意的方法参数名(如#argName)或参数索引(如#a0或#p0) `#Argument

3.Spring配置Ehcache缓存

3.1 Ehcache缓存简介

EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点。它是Hibernate中的默认缓存框架。
- 主要的特性有:
1. 快速
2. 简单
3. 多种缓存策略
4. 缓存数据有两级:内存和磁盘,因此无需担心容量问题
5. 缓存数据会在虚拟机重启的过程中写入磁盘
6. 可以通过RMI、可插入API等方式进行分布式缓存
7. 具有缓存和缓存管理器的侦听接口
8. 支持多缓存管理器实例,以及一个实例的多个缓存区域
9. 提供Hibernate的缓存实现

3.2 配置Ehcache缓存

第一步: maven 依赖添加

<dependency>   <groupId>net.sf.ehcache</groupId>   <artifactId>ehcache</artifactId>   <version>${ehcache.version}</version></dependency>  <!-- 这个jar包中含有Spring对于缓存功能的抽象封装接口。--><dependency>  <groupId>org.springframework</groupId>  <artifactId>spring-context-support</artifactId>  <version>${spring.version}</version></dependency>

第二步: applicationContext.xml 配置

 <!-- 在spring.xml的配置文件中引入schema -->   xmxmlns:cache="http://www.springframework.org/schema/cache"   http://www.springframework.org/schema/cache    http://www.springframework.org/schema/cache/spring-cache-3.2.xsd   <!-- 启用缓存注解功能,这个是必须的,否则注解不会生效,另外,该注解一定要声明在spring主配置文件中才会生效 -->   <cache:annotation-driven cache-manager="ehcacheManager"/>  <!-- 声明Ehcache缓存管理器 -->   <bean id="ehcacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">        <property name="cacheManager" ref="ehcacheManagerFactory" />   </bean>   <!-- 加载Ehcache配置 -->   <bean id="cacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">             <property name="configLocation" value="classpath:ehcache.xml"/>    </bean> 

第三步: 配置ehcache.xml

  <?xml version="1.0" encoding="UTF-8"?>  <ehcache>  <!-- 磁盘缓存位置 -->    <diskStore path="java.io.tmpdir"/>    <!-- 默认缓存 -->  <defaultCache            maxEntriesLocalHeap="10000"            eternal="false"            overflowToDisk="false"             timeToIdleSeconds="120"            timeToLiveSeconds="120"            diskSpoolBufferSizeMB="30"            maxEntriesLocalDisk="10000000"            diskExpiryThreadIntervalSeconds="120"           memoryStoreEvictionPolicy="LRU">        <persistence strategy="localTempSwap"/>  </defaultCache>  <!-- 自定义缓存 -->  <cache name="myCache"           maxEntriesLocalHeap="10000"           maxEntriesLocalDisk="1000"           eternal="false"           diskSpoolBufferSizeMB="30"           timeToIdleSeconds="300"           timeToLiveSeconds="600"           memoryStoreEvictionPolicy="LFU"           transactionalMode="off">        <persistence strategy="localTempSwap"/>    </cache>     </ehcache>  

3.3 Ehcache 配置参数介绍

参数 含义 < diskStore> 当内存缓存中对象数量超过maxElementsInMemory时,将缓存对象写到磁盘缓存中(需对象实现序列化接口) < diskStore path=”“> 用来配置磁盘缓存使用的物理路径,Ehcache磁盘缓存使用的文件后缀名是.data和.index name “缓存名称,cache的唯一标识(ehcache会把这个cache放到HashMap里) maxEntriesLocalHeap=”1000” 堆内存中最大缓存对象数,0没有限制(必须设置) maxEntriesLocalDisk=”1000” 磁盘缓存中最多可以存放的元素数量,0表示无穷大 maxElementsInMemory 内存缓存中最多可以存放的元素数量,若放入Cache中的元素超过这个数值,则有以下两种情况:1.若overflowToDisk=true,则会将Cache中多出的元素放入磁盘文件中. 2.若overflowToDisk=false,则根据memoryStoreEvictionPolicy策略替换Cache中原有的元素 overflowToDisk=”false” 内存不足时,是否启用磁盘缓存(即内存中对象数量达到maxElementsInMemory时,Ehcache会将对象写到磁盘中) , 会根据标签中path值查找对应的属性值,写入磁盘的文件会放在path文件夹下,文件的名称是cache的名称,后缀名是data memoryStoreEvictionPolicy=”LFU” 内存存储与释放策略,即达到maxElementsInMemory限制时,Ehcache会根据指定策略清理内存.共有三种策略,分别为LRU(最近最少使用)、LFU(最常用的)、FIFO(先进先出) eternal=”false” 缓存中对象是否永久有效,即是否永驻内存,true时将忽略timeToIdleSeconds和timeToLiveSeconds(必须设置) timeToIdleSeconds=”0” 缓存数据在失效前的允许闲置时间(单位:秒),仅当eternal=false时使用,默认值是0表示可闲置时间无穷大,此为可选属性 即访问这个cache中元素的最大间隔时间,若超过这个时间没有访问此Cache中的某个元素,那么此元素将被从Cache中清除 timeToLiveSeconds=”600” 缓存数据在失效前的允许存活时间(单位:秒),仅当eternal=false时使用,默认值是0表示可存活时间无穷大即Cache中的某元素从创建到清楚的生存时间,也就是说从创建开始计时,当超过这个时间时,此元素将从Cache中清除 diskPersistent=”false” 磁盘缓存在JVM重新启动时是否保持(默认为false) ,当这个属性的值为true时,系统在初始化时会在磁盘中查找文件名为cache名称,后缀名为index的文件 这个文件中存放了已经持久化在磁盘中的cache的index,找到后会把cache加载到内存 要想把cache真正持久化到磁盘,写程序时注意执行net.sf.ehcache.Cache.put(Element element)后要调用flush()方法 clearOnFlush 内存数量最大时是否清除 diskExpiryThreadIntervalSeconds 磁盘失效线程运行时间间隔,默认是120秒 diskSpoolBufferSizeMB 这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。

3.4 注意事项

  • 要实现缓存的实体必须要序列化
原创粉丝点击