单一缓存方案
使用SpringBoot提供的统一缓存接口spring-boot-starter-cache, 以下的几个例子都是spring-boot-starter-cache的具体底层实现,但是不推荐使用这些,功能不灵活。只是介绍
提前准备的类
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class Book {
private Integer id;
private String name;
private String description;
public Book(Integer id, String name, String description) {
this.id = id;
this.name = name;
this.description = description;
System.out.println("Book 创建完成"+ this.id);
}
}
1.SpringBoot内置缓存方案(Simple)
springboot技术提供有内置的缓存解决方案,可以帮助开发者快速开启缓存技术,并使用缓存技术进行数据的快速操作
步骤①:导入springboot提供的缓存技术对应的starter
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
步骤②:启用缓存,在引导类上方标注注解@EnableCaching配置springboot程序中可以使用缓存
@SpringBootApplication
//开启缓存功能
@EnableCaching
public class Springboot19CacheApplication {
public static void main(String[] args) {
SpringApplication.run(Springboot19CacheApplication.class, args);
}
}
步骤③:设置获得的数据是否来自于缓存
@Service
public class BookService {
@Cacheable(value = "cache_namespace",key = "#id")
public Book getById(Integer id) {
return Book.builder()
.id(id)
.name("book_name" + id)
.description("book_desc" + id)
.build();
}
}
在业务方法上面使用注解@Cacheable声明当前方法的返回值放入缓存中,其中要指定缓存的存储位置,以及缓存中保存当前方法返回值对应的名称。上例中value属性描述缓存的存储位置,可以理解为是一个存储空间名,key属性描述了缓存中保存数据的名称,使用#id读取形参中的id值作为缓存名称。
使用@Cacheable注解后,执行当前操作,如果发现对应名称在缓存中没有数据,就正常Build数据,然后放入缓存;如果对应名称在缓存中有数据,就终止当前业务方法执行,直接返回缓存中的数据。
缺点: 无法设置过期时间等,灵活性差
2.SpringBoot整合Ehcache缓存
步骤①:导入Ehcache的坐标
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
此处为什么不是导入Ehcache的starter,而是导入技术坐标呢?其实springboot整合缓存技术做的是通用格式,不管你整合哪种缓存技术,只是实现变化了,操作方式一样。
步骤②:配置缓存技术实现使用Ehcache
spring:
cache:
type: ehcache
ehcache:
config: classpath:ehcache.xml
ehcache.xml配置如下
<?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">
<diskStore path="D:\ehcache" />
<!--默认缓存策略 -->
<!-- external:是否永久存在,设置为true则不会被清除,此时与timeout冲突,通常设置为false-->
<!-- diskPersistent:是否启用磁盘持久化-->
<!-- maxElementsInMemory:最大缓存数量-->
<!-- overflowToDisk:超过最大缓存数量是否持久化到磁盘-->
<!-- timeToIdleSeconds:最大不活动间隔,设置过长缓存容易溢出,设置过短无效果,可用于记录时效性数据,例如验证码-->
<!-- timeToLiveSeconds:最大存活时间-->
<!-- memoryStoreEvictionPolicy:缓存清除策略-->
<defaultCache
eternal="false"
diskPersistent="false"
maxElementsInMemory="1000"
overflowToDisk="false"
timeToIdleSeconds="60"
timeToLiveSeconds="60"
memoryStoreEvictionPolicy="LRU" />
<cache
name="myNameSpace"
eternal="false"
diskPersistent="false"
maxElementsInMemory="1000"
overflowToDisk="false"
timeToIdleSeconds="10"
timeToLiveSeconds="10"
memoryStoreEvictionPolicy="LRU" />
</ehcache>
注意前面的案例中,设置了数据保存的位置是myNameSpace
@Service
public class BookService {
@Cacheable(value = "myNameSpace",key = "#id")
public Book getById(Integer id) {
return Book.builder()
.id(id)
.name("book_name" + id)
.description("book_desc" + id)
.build();
}
}
到这里springboot整合Ehcache就做完了,可以发现一点,原始代码没有任何修改,仅仅是加了一组配置就可以变更缓存供应商了,这也是springboot提供了统一的缓存操作接口的优势,变更实现并不影响原始代码的书写。
3.SpringBoot整合Redis缓存
推荐使用jetcache或者Redis本身的API进行缓存操作
步骤①:导入redis的坐标
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependenc