我的简单理解
Ehcache 我的简单理解
- Ehcache 是进程内缓存,就是Ehcache的缓存占用的存储空间,和JAVA虚拟机是在一块儿的,也就是说随着缓存的增多,java虚拟机所消耗的内存也会变大。。这是与redis最明显的区别。。
- 因为Ehcache 缓存和java虚拟机在一起,所以读写速度自然也是极快的。
- Ehcach的工作机制就是,当一个请求来了之后,如果我们在查询的方法上添加了@Cacheable注解,则会先去缓存里面查找数据,如果缓存中有则直接返回,没有则执行方法去数据库查询。
1 添加依赖
<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.4</version>
</dependency>
2 新建立一个Mycache.xml文件放在,类路径下。
xml 文件主要用来配置Ehcache 如下
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
updateCheck="false">
<!--指定一个文件目录,当EhCache把数据写到硬盘上时,将把数据写到这个文件目录下
user.home : 用户主目录
user.dir : 用户当前工作目录
java.io.tmpdir : 默认临时文件路径
-->
<diskStore path="java.io.tmpdir/Tmp_EhCache"/>
<!--
name: 缓存名称
eternal: true表示对象永不过期,此时会忽略timeToIdleSeconds和timeToLiveSeconds属性,默认为false
timeToIdleSeconds: 设定允许对象处于空闲状态的最长时间,以秒为单位。当对象自从最近一次被访问后,如果处于空闲状态的时间超过了timeToIdleSeconds属性值,这个对象就会过期,EHCache将把它从缓存中清空。只有当eternal属性为false,该属性才有效。如果该属性值为0,则表示对象可以无限期地处于空闲状态
timeToLiveSeconds: 设定对象允许存在于缓存中的最长时间,以秒为单位。当对象自从被存放到缓存中后,如果处于缓存中的时间超过了 timeToLiveSeconds属性值,这个对象就会过期,EHCache将把它从缓存中清除。只有当eternal属性为false,该属性才有效。如果该属性值为0,则表示对象可以无限期地存在于缓存中。timeToLiveSeconds必须大于timeToIdleSeconds属性,才有意义
maxElementsInMemory: 内存中最大缓存对象数;maxElementsInMemory界限后,会把溢出的对象写到硬盘缓存中。注意:如果缓存的对象要写入到硬盘中的话,则该对象必须实现了Serializable接口才行
memoryStoreEvictionPolicy: 当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。可选策略有:LRU(最近最少使用,默认策略)、FIFO(先进先出)、LFU(最少访问次数)
maxElementsOnDisk: 硬盘中最大缓存对象数,若是0表示无穷大
overflowToDisk: 是否保存到磁盘,当系统宕机时
diskPersistent: 是否缓存虚拟机重启期数据,是否持久化磁盘缓存,当这个属性的值为true时,系统在初始化时会在磁盘中查找文件名为cache名称,后缀名为index的文件,这个文件中存放了已经持久化在磁盘中的cache的index,找到后会把cache加载到内存,要想把cache真正持久化到磁盘,写程序时注意执行net.sf.ehcache.Cache.put(Element element)后要调用flush()方法
diskSpoolBufferSizeMB: 这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区
diskExpiryThreadIntervalSeconds: 磁盘失效线程运行时间间隔,默认为120秒
clearOnFlush: 内存数量最大时是否清除
-->
<!--defaultCache:默认缓存策略,当ehcache找不到定义的缓存时,则默认缓存策略-->
<defaultCache eternal="false" maxElementsInMemory="1000" overflowToDisk="true"
diskPersistent="true"
timeToIdleSeconds="0" timeToLiveSeconds="600" memoryStoreEvictionPolicy="LRU"/>
<cache
name="myCache"
eternal="false"
maxElementsInMemory="200"
overflowToDisk="false"
diskPersistent="true"
timeToIdleSeconds="0"
timeToLiveSeconds="300"
memoryStoreEvictionPolicy="LRU"/>
</ehcache>
里面可以添加若干个<cache …/>标签,,每个cache标签对一个cache进行配置。
配置类
@Configuration
@EnableCaching
public class MyEhcacheConfig {
@Bean
public EhCacheCacheManager ehCacheCacheManager(EhCacheManagerFactoryBean bean) {
return new EhCacheCacheManager(bean.getObject());
}
/**
* 据shared与否的设置,
* Spring分别通过CacheManager.create()
* 或new CacheManager()方式来创建一个ehcache基地.
* 也说是说通过这个来设置cache的基地是这里的Spring独用,还是跟别的(如hibernate的Ehcache共享)
*
* @return
*/
@Bean
public EhCacheManagerFactoryBean ehCacheManagerFactoryBean() {
EhCacheManagerFactoryBean cacheManagerFactoryBean = new EhCacheManagerFactoryBean();
cacheManagerFactoryBean.setConfigLocation(new ClassPathResource("mycache.xml"));
cacheManagerFactoryBean.setShared(true);
return cacheManagerFactoryBean;
}
}
通过以上配置类我们就产生了一个EhcacheManager 。
接下来我们至于要在需要添加缓存,和删除缓存的地方加注解就可以实现缓存的基本功能了。
通常注解我们加在Service层中,也可以加在Controller层
如下就可以实现在查询的时候添加缓存,在删除的时候删除缓存,,对应在更改的时候也应该删除缓存。
@GetMapping("work/{id}")
@Cacheable(value = "myCache", key = "#id")
public WorkInfo getWorkInfo(@PathVariable Integer id) {
return workInfoService.getById(id);
}
@GetMapping("work/delete/{id}")
@CacheEvict(value = "myCache", key = "#id")
public boolean deleteWorkInfo(@PathVariable Integer id) {
return workInfoService.removeById(id);
}
常用的几个注解的说明
@Cacheable() 参数如下
- name 缓存的名字 对应xml文件的cache的name
- key 键 可以缺省,默认值按照KeyGenerator的生成策略
- condition 条件 看,条件满足则添加缓存
@CacheEvict()
- name 缓存的名字 对应xml文件的cache的name
- key 键 可以缺省,默认值按照KeyGenerator的生成策略
- condition 条件 看,条件满足则添加缓存
- allEntries 清除该缓存中的所有内容
- beforeInvocation booble 在执行方法之前清除缓存
@CachePut()
- 与@Cacheable相同的是,@CachePut 功能是将数据添加入缓存
- 与@Cacheable不同的是,@CachePut 不会先去判断缓存里面是否有符合的数据,而是每次都去执行方法,并将方法的返回值放进cache中。