1.什么是encache
EhCache 是一个纯 Java 的进程内缓存框架,具有快速、精干等特点,是 Hibernate 中默认的 CacheProvider。
Ehcache 特性
优点
- 快速、简单
- 支持多种缓存策略:LRU、LFU、FIFO 淘汰算法
- 缓存数据有两级:内存和磁盘,因此无需担心容量问题
- 缓存数据会在虚拟机重启的过程中写入磁盘
- 可以通过 RMI、可插入 API 等方式进行分布式缓存
- 具有缓存和缓存管理器的侦听接口
- 支持多缓存管理器实例,以及一个实例的多个缓存区域
- 提供 Hibernate 的缓存实现
缺点
- 使用磁盘 Cache 的时候非常占用磁盘空间
- 不保证数据的安全
- 虽然支持分布式缓存,但效率不高(通过组播方式,在不同节点之间同步数据)。
2.代码工程
实验目标
利用encache实现service层缓存功能
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>springboot-demo</artifactId>
<groupId>com.et</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ehcache</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
</dependencies>
</project>
controller
package com.et.controller;
import com.et.service.HelloService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
public class HelloWorldController {
@Autowired
HelloService helloService;
@RequestMapping("/hello")
public Map<String, Object> showHelloWorld(String name){
Map<String, Object> map = new HashMap<>();
map.put("msg", helloService.sayhi(name));
return map;
}
}
service
@Cacheable
表明所修饰的方法是可以缓存的:当第一次调用这个方法时,它的结果会被缓存下来,在缓存的有效时间内,以后访问这个方法都直接返回缓存结果,不再执行方法中的代码段。
这个注解可以用
condition
属性来设置条件,如果不满足条件,就不使用缓存能力,直接执行方法。
可以使用
key
属性来指定 key 的生成规则。
@CachePut
与
@Cacheable
不同,
@CachePut
不仅会缓存方法的结果,还会执行方法的代码段。
它支持的属性和用法都与
@Cacheable
一致。
@CacheEvict
与
@Cacheable
功能相反,
@CacheEvict
表明所修饰的方法是用来删除失效或无用的缓存数据。
package com.et.service;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
/**
* @ClassName Hello
* @Description TODO
* @Author liuhaihua
* @Date 2024/10/4 20:24
* @Version 1.0
*/
@Service
public class HelloService {
@Cacheable(value = "customcache")
public String sayhi(String name){
System.out.println("name:"+name);
return "hi,"+name;
}
}
DemoApplication.java
package com.et;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication
@EnableCaching
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
application.yaml
springboot在启动的时候可以对ehcache.xml配置文件进行解析,拿到缓存策略,交给ehcache去缓存处理。
server:
port: 8088
spring:
cache:
ehcache:
config: classpath:config/encache.xml
encache.xml
Ehcache 的
CacheManager
构造函数或工厂方法被调用时,会默认加载 classpath 下名为
ehcache.xml的配置文件。如果加载失败,会加载 Ehcache jar 包中的
ehcache-failsafe.xml文件,这个文件中含有简单的默认配置。
ehcache.xml 配置参数说明:
- name:缓存名称。
- maxElementsInMemory:缓存最大个数。
- eternal:缓存中对象是否为永久的,如果是,超时设置将被忽略,对象从不过期。
- timeToIdleSeconds:置对象在失效前的允许闲置时间(单位:秒)。仅当 eternal=false 对象不是永久有效时使用,可选属性,默认值是 0,也就是可闲置时间无穷大。
- timeToLiveSeconds:缓存数据的生存时间(TTL),也就是一个元素从构建到消亡的最大时间间隔值,这只能在元素不是永久驻留时有效,如果该值是 0 就意味着元素可以停顿无穷长的时间。
- maxEntriesLocalDisk:当内存中对象数量达到 maxElementsInMemory 时,Ehcache 将会对象写到磁盘中。
- overflowToDisk:内存不足时,是否启用磁盘缓存。
- diskSpoolBufferSizeMB:这个参数设置 DiskStore(磁盘缓存)的缓存区大小。默认是 30MB。每个 Cache 都应该有自己的一个缓冲区。
- maxElementsOnDisk:硬盘最大缓存个数。
- diskPersistent:是否在 VM 重启时存储硬盘的缓存数据。默认值是 false。
- diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是 120 秒。
- memoryStoreEvictionPolicy:当达到 maxElementsInMemory 限制时,Ehcache 将会根据指定的策略去清理内存。默认策略是 LRU(最近最少使用)。你可以设置为 FIFO(先进先出)或是 LFU(较少使用)。
- clearOnFlush:内存数量最大时是否清除。
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
maxElementsOnDisk="10000000"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
<persistence strategy="localTempSwap"/>
</defaultCache>
<!-- Custom cache strategy. The name attribute value of the custom cache strategy is users. If you define multiple cache strategies, the name values cannot be the same. -->
<cache name="customcache"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
maxElementsOnDisk="10000000"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
<persistence strategy="localTempSwap"/>
</cache>
</ehcache>
3.测试
- 启动SpringBoot应用
- 连续二次访问http://127.0.0.1:8088/hello?name=jack
- 可以看出第一次会进去方法里面,并返回
name:jack,第二次直接从encache拿到缓存内容,而不会进去方法
4.引用