EhCache是一个比较成熟的Java缓存框架,最早从hibernate发展而来, 是进程中的缓存系统,它提供了用内存,磁盘文件存储,以及分布式存储方式等多种灵活的cache管理方案,快速简单。
网上很多教程都没说完整,本文写的代码都是经过实践测试出来的的结果。
1、引入MAVEN
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.10.2</version>
</dependency>
2、编写ehcache.xml配置文件,放到resources文件夹下
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
<!-- 磁盘缓存位置 -->
<diskStore path="D:\testEhcache"/>
<!-- defaultCache:echcache的默认缓存策略 -->
<defaultCache
maxElementsInMemory="50000"
maxElementsOnDisk="100000"
overflowToDisk="true"
diskPersistent="false"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
diskSpoolBufferSizeMB="50"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LFU"/>
<!-- 自定义缓存策略 -->
<cache name="test"
maxElementsInMemory="1"
maxElementsOnDisk="100000"
overflowToDisk="true"
diskPersistent="true"
timeToIdleSeconds="0"
timeToLiveSeconds="21600"
diskSpoolBufferSizeMB="50"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="FIFO"/>
</ehcache>
下面为属性全属性介绍:
<diskStore path="java.io.tmpdir/Tmp_EhCache"/> : 默认临时文件路径
name : 缓存名称。
maxElementsInMemory : 缓存最大数目
maxElementsOnDisk :硬盘最大缓存个数。
eternal : 对象是否永久有效,一但设置了,timeout将不起作用。
overflowToDisk : 是否保存到磁盘,当系统当机时
timeToIdleSeconds : 设置对象在失效前的允许闲置时间(单位:秒)。
仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
timeToLiveSeconds : 设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。
仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
diskPersistent :是否缓存虚拟机重启期数据
diskSpoolBufferSizeMB :这个参数设置DiskStore(磁盘缓存)的缓存区大小。
默认是30MB。每个Cache都应该有自己的一个缓冲区。
diskExpiryThreadIntervalSeconds :磁盘失效线程运行时间间隔,默认是120秒。
memoryStoreEvictionPolicy :当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。
默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
clearOnFlush :内存数量最大时是否清除。
memoryStoreEvictionPolicy : 可选策略有:LRU(最近最少使用,默认策略)、FIFO(先进先出)、LFU(最少访问次数)。
FIFO,先进先出。
LFU,直白一点就是讲一直以来最少被使用的。如上面所讲,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。
LRU,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。
3、在application.properties中指定文件路径
spring.cache.ehcache.config=classpath:ehcache.xml
4、在Application.java中加入@EnableCaching注解,启动缓存启动器
@EnableCaching
public class Application {
public static void main(String[] args) {
SpringApplication.run(app.class, args);
}
}
5、使用场景
以在数据库中查询一个结果为例,我用一个字符串代表数据库结果,现需要将结果缓存起来,用Ehcache实现这个过程。
service层:
package com.service;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@Service
public class TestCache {
/**
* 缓存数据和查询缓存
*/
@Cacheable(value = "test", key = "#key")
public String getConfigure(String key) {
return "oldConfigure";
}
/**
* 缓存数据
*/
@CachePut(value = "test", key = "#key")
public String updateConfigure(String key) {
return "newConfigure";
}
/**
* 清除缓存
*/
@CacheEvict(value = "test", key = "#key")
public void cleanConfigure(String key) {
System.out.println("缓存清除成功");
}
/**
* 清除缓存
*/
@CacheEvict(value = "test", allEntries = true)
public void cleanAll() {
System.out.println("缓存清除成功");
}
}
controller层:
/**
* 缓存数据和查询缓存
*/
@RequestMapping("/getCache")
public String getCache() {
return testCache.getConfigure("configure");
}
/**
* 缓存数据
*/
@RequestMapping("/setCache")
public String setCache() {
return testCache.updateConfigure("configure");
}
/**
* 清除缓存
*/
@RequestMapping("/cleanCache")
public void cleanCache() {
testCache.cleanConfigure("configure");
}
/**
* 清除缓存
*/
@RequestMapping("/cleanAll")
public void cleanAllCache() {
testCache.cleanAll();
}
6、结果
调用过程:1、获取缓存数据;2、修改缓存数据;3、获取缓存数据;4、清除缓存数据;5、获取缓存数据
7、优化
package com.service;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@Service
@CacheConfig(cacheNames = {"test"})
public class TestCache {
/**
* 缓存数据和查询缓存
*/
@Cacheable
public String getConfigure(String key) {
return "oldConfigure";
}
/**
* 缓存数据
*/
@CachePut
public String updateConfigure(String key) {
return "newConfigure";
}
/**
* 清除缓存
*/
@CacheEvict
public void cleanConfigure(String key) {
System.out.println("缓存清除成功");
}
/**
* 清除缓存
*/
@CacheEvict(allEntries = true)
public void cleanAll() {
System.out.println("缓存清除成功");
}
}
8、补充
(1)key支持SpEL上下文数据
图片来源:https://www.jianshu.com/p/e9b40acb2993
例如:@Cacheable(key = "targetClass + methodName +#p0")
表示类名+方法名+第一个参数 拼接 key
(2)实体存为缓存的时候,需要实例化,继承 Serializable
(3)@CacheEvict 的 beforeInvocation 属性表示在执行方法之前执行缓存操作,避免出现异常时缓存没执行
相关文章:
Springboot整合cache缓存到redis:https://blog.csdn.net/zhangjian8641/article/details/108246750