【SpringBoot】 集成 Ehcache

SpringBoot ehcache 缓存

简介

EhCache 是一个纯 Java 的进程内缓存框架,具有快速、精干等特点,
是 Hibernate 中默认CacheProvider。Ehcache 是一种广泛使用的开源 Java 分布式缓存。
主要面向通用缓存,Java EE 和轻量级容器。它具有内存和磁盘存储,缓存加载器,缓存扩展,缓存异常处理程序,一个 gzip 缓存 servlet 过滤器,支持 REST 和 SOAP api 等特点。

特性

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

与 Redis 相比

  1. EhCache 直接在jvm虚拟机中缓存,速度快,效率高;但是缓存共享麻烦,集群分布式应用不方便。
  2. Redis 是通过 Socket 访问到缓存服务,效率比 EhCache 低,比数据库要快很多,处理集群和分布式缓存方便,有成熟的方案。如果是单个应用或者对缓存访问要求很高的应用,用 EhCache 。如果是大型系统,存在缓存共享、分布式部署、缓存内容很大的,建议用 Redis。
  3. EhCache 也有缓存共享方案,不过是通过 RMI 或者 Jgroup 多播方式进行广播缓存通知更新,缓存共享复杂,维护不方便;简单的共享可以,但是涉及到缓存恢复,大数据缓存,则不合适。

相关配置

核心依赖文件

<!-- Spring Boot 缓存支持启动器 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- Ehcache 坐标 -->
<dependency>
    <groupId>net.sf.ehcache</groupId>
    <artifactId>ehcache</artifactId>
</dependency>

ehcache.xml

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
<!--  diskStore 这个是磁盘存储路径,当内存缓存满了的时候,就会往这里面放,java.io.tmdir是操作系统缓存的临时目录,不同操作系统缓存目录不一样。-->
    <diskStore path="java.io.tmpdir"/>

    <!--defaultCache:echcache的默认缓存策略  -->
    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            maxElementsOnDisk="10000000"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU">
        <persistence strategy="localTempSwap"/>
    </defaultCache>
    
    <!--以下为自定义的缓存策略  -->
    <cache name="dictCache"
           maxElementsInMemory="10000"
           eternal="false"
           timeToIdleSeconds="120"
           timeToLiveSeconds="120"
           maxElementsOnDisk="10000000"
           diskExpiryThreadIntervalSeconds="120"
           memoryStoreEvictionPolicy="LRU">
        <persistence strategy="localTempSwap"/>
    </cache>
</ehcache>

标签说明

  • diskStore: 这个是磁盘存储路径,当内存缓存满了的时候,就会往这里面放,java.io.tmdir是操作系统缓存的临时目录,不同操作系统缓存目录不一样。

  • maxElementsInMemory: 内存缓存中最多可以存放的元素数量,若放入Cache中的元素超过这个数值,则有以下两种情况

    1. 若overflowToDisk=true,则会将Cache中多出的元素放入磁盘文件中
    2. 若overflowToDisk=false,则根据memoryStoreEvictionPolicy策略替换Cache中原有的元素
  • overflowToDisk : 内存不足时,是否启用磁盘缓存

  • eternal: 缓存中对象是否永久有效

  • timeToIdleSeconds: 缓存数据在失效前的允许闲置时间(单位:秒),仅当eternal=false时使用,默认值是0表示可闲置时间无穷大,若超过这个时间没有访问此Cache中的某个元素,那么此元素将被从Cache中清除

  • timeToLiveSeconds: 缓存数据的总的存活时间(单位:秒),仅当eternal=false时使用,从创建开始计时,失效结束。

  • maxElementsOnDisk: 磁盘缓存中最多可以存放的元素数量,0表示无穷大

  • diskExpiryThreadIntervalSeconds: 磁盘缓存的清理线程运行间隔,默认是120秒

  • memoryStoreEvictionPolicy: 内存存储与释放策略,即达到maxElementsInMemory限制时,Ehcache会根据指定策略清理内存 共有三种策略,分别为LRU(最近最少使用)、LFU(最常用的)、FIFO(先进先出)

application.xml

spring:
  cache:
    ehcache:
      config: classpath:ehcache.xml

启动类

加上以下注解

@EnableCaching

用法实例:

以下以业务字典作为demo演示;

注意:待缓存的对象需要实现 可序列化接口Serializable;由于需要实体类支持缓存中的磁盘存储,所以需要实体类实现可序列化接口

@Data
public class SysDic implements Serializable {
    //主键
    private Integer dicId;
    //业务场景编码
    private String busiSceneCode;
    //字典编码
    private String dicCode;
    //字典名称
    private String dicName;
    //显示顺序
    private Integer displayOrder;
    //创建人
    private String createStaff;
    //创建时间
    private Date createTime;
    //最后修改时间
    private Date lastModiTime;
    //状态(1有效 0无效)
    private Integer status;
    // 备注
    private String remark;
}

数据缓存

@Cacheable(value = "dictCache", key = "#sysDic.busiSceneCode")
@Override
public IPage<SysDic> queryPage(Page<SysDic> page, SysDic sysDic) {
    return  this.baseMapper.selectPage(page, new QueryWrapper<SysDic>(sysDic));
}

@Cacheable 注解说明:

  1. @Cacheable可以标记在一个方法或一个类上;
    2. 当标记在一个方法上时表示该方法是支持缓存的;
    3. 当标记在一个类上时则表示该类所有的方法都是支持缓存的。

  2. @Cacheable可以指定三个属性,value、key和condition。

    1. value: 指定cache的名称(即选择ehcache.xml中哪种缓存方式存储)
    2. key: 用来指定Spring缓存方法的返回结果时对应的key的。该属性支持SpringEL表达式。当我们没有指定该属性时,Spring将使用默认策略生成key。我们也直接使用“#参数名”或者“#p参数index”.

@Cacheable 参数示例:

@Cacheable(value="dictCache", key="#id")
public SysDic find(Integer id) {
    return null;
}

@Cacheable(value="dictCache", key="#p0")
public SysDic find(Integer id) {
    return null;
}

@Cacheable(value="dictCache", key="#sysDic.id")
public SysDic find(SysDic sysDic) {
    return null;
}

@Cacheable(value="dictCache", key="#p0.id")
public SysDic find(SysDic sysDic) {
   return null;
}

清除缓存

@CacheEvict(value = "dictCache", allEntries = true)
public boolean insert(SysDic sysDic) {
    return this.baseMapper.insert(sysDic) > 0 ? true : false;
}

@CacheEvict(value = "dictCache", allEntries = true)
@Override
public boolean updateDicById(SysDic sysDic) {
    return this.baseMapper.updateById(sysDic) > 0 ? true : false;
}

@CacheEvict(value = "dictCache", allEntries = true)
@Override
public boolean deleteByDicId(List<Long> idList) {
  return this.baseMapper.deleteBatchIds(idList) > 0 ? true : false;
}

@CacheEvict 注解说明

  1. @CacheEvict是用来标注在需要清除缓存元素的方法或类上的。 当标记在一个类上时表示其中所有的方法的执行都会触发缓存的清除操作。
  2. @CacheEvict可以指定的属性有value、key、condition、allEntries和beforeInvocation。 其中value、key和condition的语义与@Cacheable对应的属性类似;allEntries是boolean类型,
    表示是否需要清除缓存中的所有元素。默认为false,表示不需要。
  3. 当指定了allEntries为true时,Spring Cache将忽略指定的key。有的时候我们需要Cache一下清除所有的元素,这比一个一个清除元素更有效率。
posted @ 2023-02-10 15:21  Hello、Lin  阅读(195)  评论(0编辑  收藏  举报