使用Spring cache和ehcache之前必须了解的(2)

condition属性默认为空,表示将缓存所有的调用情形。其值是通过SpringEL表达式来指定的,当为true时表示进行缓存处理;当为false时表示不进行缓存处理,即每次调用该方法时该方法都会执行一次。如下示例表示只有当user的id为偶数时才会进行缓存

@Cacheable(value={"users"}, key="#user.id", condition="#user.id%2==0")

public User find(User user) {

System.out.println("find user by user " + user);

return user;

}

属性四 :allEntries

是boolean类型,表示是否需要清除缓存中的所有元素。默认为false,表示不需要。当指定了allEntries为true时,Spring Cache将忽略指定的key。有的时候我们需要Cache一下清除所有的元素,这比一个一个清除元素更有效率。

@CacheEvict(value="users", allEntries=true)

public void delete(Integer id) {

System.out.println("delete user by id: " + id);

}

属性五 :beforeInvocation

清除操作默认是在对应方法成功执行之后触发的,即方法如果因为抛出异常而未能成功返回时也不会触发清除操作。使用beforeInvocation可以改变触发清除操作的时间,当我们指定该属性值为true时,Spring会在调用该方法之前清除缓存中的指定元素。

@CacheEvict(value="users", beforeInvocation=true)

public void delete(Integer id) {

System.out.println("delete user by id: " + id);

}

注意我们也可以使用ehcache的去除策略最近使用(LRU)"策略,其它还有先入先出FIFO,最少使用LFU,较少使用LRU

基于注解配置:

配置Spring对基于注解的Cache的支持,首先我们需要在Spring的配置文件中引入cache命名空间,其次通过<cache:annotation-driven />就可以启用Spring对基于注解的Cache的支持。

<cache:annotation-driven/>有一个mode属性,可选值有proxy和aspectj。默认是使用proxy。当mode为proxy时,只有缓存方法在外部被调用的时候Spring Cache才会发生作用,这也就意味着如果一个缓存方法在其声明对象内部被调用时Spring Cache是不会发生作用的。而mode为aspectj时就不会有这种问题。另外使用proxy时,只有public方法上的@Cacheable等标注才会起作用,如果需要非public方法上的方法也可以使用Spring Cache时把mode设置为aspectj。此外,<cache:annotation-driven/>还可以指定一个proxy-target-class属性,表示是否要代理class,默认为false。我们前面提到的@Cacheable、@cacheEvict等也可以标注在接口上,这对于基于接口的代理来说是没有什么问题的,但是需要注意的是当我们设置proxy-target-class为true或者mode为aspectj时,是直接基于class进行操作的,定义在接口上的@Cacheable等Cache注解不会被识别到,那对应的Spring Cache也不会起作用了。

需要注意的是<cache:annotation-driven/>只会去寻找定义在同一个ApplicationContext下的@Cacheable等缓存注解。

基于XML配置:

<cache:advice cache-manager="cacheManager">

<cache:caching cache="users">

<cache:cacheable method="findById" key="#p0"/>

<cache:cacheable method="find" key="#user.id"/>

<cache:cache-evict method="deleteAll" all-entries="true"/>

</cache:caching>

</cache:advice>

上面配置定义了一个名为cacheAdvice的cache:advice,其中指定了将缓存findById方法和find方法到名为users的缓存中。这里的方法还可以使用通配符“*”,比如“find*”表示任何以“find”开始的方法。有了cache:advice之后,我们还需要引入aop命名空间,然后通过aop:config指定定义好的cacheAdvice要应用在哪些pointcut上。如:

1    <aop:config proxy-target-class="false">
2
3      <aop:advisor advice-ref="cacheAdvice" pointcut="execution(* com.xxx.UserService.*(..))"/>
4
5    </aop:config>

二.EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点。

ehcache官网: 可以下载文档看看,里面写的很清楚。

主要的特性有:

1. 快速

2. 简单

3. 多种缓存策略

4. 缓存数据有两级:内存和磁盘,因此无需担心容量问题

5. 缓存数据会在虚拟机重启的过程中写入磁盘

6. 可以通过RMI、可插入API等方式进行分布式缓存

7. 具有缓存和缓存管理器的侦听接口

8. 支持多缓存管理器实例,以及一个实例的多个缓存区域

9. 提供Hibernate的缓存实现

ehcache.xml:里面的注释写的很清楚了。

<diskStore>  : 当内存缓存中对象数量超过maxElementsInMemory时,将缓存对象写到磁盘缓存中(需对象实现序列化接口) 
<diskStore path="">    : 用来配置磁盘缓存使用的物理路径,Ehcache磁盘缓存使用的文件后缀名是*.data和*.index 
name : "缓存名称,cache的唯一标识(ehcache会把这个cache放到HashMap里) 
maxElementsInMemory  : 缓存最大个数。
eternal="false"  : 对象是否永久有效,一但设置了,timeout将不起作用。 (必须设置)
maxEntriesLocalHeap="1000"  : 堆内存中最大缓存对象数,0没有限制(必须设置)
maxEntriesLocalDisk= "1000"  : 硬盘最大缓存个数。
overflowToDisk="false"  : 当缓存达到maxElementsInMemory值是,是否允许溢出到磁盘(必须设置)(内存不足时,是否启用磁盘缓存。)
diskSpoolBufferSizeMB  : 这个参数设置DiskStore(磁盘缓存)的缓存区大小。��认是30MB。每个Cache都应该有自己的一个缓冲区。
diskPersistent="false"  : 磁盘缓存在JVM重新启动时是否保持(默认为false)
 timeToIdleSeconds="0"  : 导致元素过期的访问间隔(秒为单位),即当缓存闲置n秒后销毁。 当eternal为false时,这个属性才有效,0表示可以永远空闲,默认为0
 timeToLiveSeconds="600"  : 元素在缓存里存在的时间(秒为单位),即当缓存存活n秒后销毁. 0 表示永远存在不过期
 memoryStoreEvictionPolicy="LFU" : 当达到maxElementsInMemory时,如何强制进行驱逐默认使用"最近使用(LRU)"策略,其它还有先入先出FIFO,最少使用LFU,较少使用LRU
 diskExpiryThreadIntervalSeconds :磁盘失效线程运行时间间隔,默认是120秒。
 clearOnFlush  : 内存数量最大时是否清除。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/c9376f744be26303e649641a57a0c26c.html