摘要
本文介绍如何为SpringBoot应用添加缓存。
正文
1 关于缓存
缓存就是数据交换的缓冲区,用来提高存取数据的速度。将经常访问又不经常改变的数据存入缓存,可以提高系统性能和吞吐量。通过设置一二级缓存:将系统内存作为一级缓存,存储热点数据;将缓存服务器作为二级缓存,存储常用数据。不仅可以保证热点数据获取的效率,还可以避免缓存占用系统过多内存。
2 Spring Boot Cache
SpringBoot提供了spring-boot-starter-cache
为多种缓存实现提供了简单且统一的使用方式。
- 缓存功能的一键启停。
- 通过注解为方法添加缓存功能。
2.1 如何使用缓存
- 加入Cache依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
- 使用@Cacheable注解为方法添加缓存功能
@Cacheable("user")
public User findById(Integer id){
// 略
}
- 使用@EnableCaching注解开启缓存功能
@EnableCaching
@SpringBootApplication
public class CacheApplication {
public static void main(String[] args) {
SpringApplication.run(CacheApplication.class, args);
}
}
2.2 缓存注解详细说明
SpringBoot提供的缓存注解有下面几种
- @Cacheable:若存在缓存,则读取缓存,跳过方法执行;若不存在缓存,则执行方法,并则将返回值存入缓存供下次使用。一般用于查询操作。
- @CacheEvict:使指定缓存失效。一般用于删除操作。
- @CachePut:将方法返回存入缓存。一般用于更新操作。
- @Cache:通过该注解可以配置多种缓存操作。
- @CacheConfig:配置当前类的公共缓存配置。
2.2.1 @Cacheable
若缓存存在,则跳过方法执行,直接返回缓存结果。
若缓存不存在,则执行方法,并将结果缓存。
2.2.2 @CachePut
将方法执行结果存入指定缓存
2.2.3 @CacheEvict
当方法执行后清除指定缓存
2.2.4 @Caching
若一个方法执行需要对缓存进行多个操作,通过该注解实现。
@Caching(
cacheable = {@Cacheable("cache1"), @Cacheable("cache2")},
evict = {@CacheEvict("cache1"), @CacheEvict("cache2")},
put = {@CachePut("cache1"), @CachePut("cache2")}
)
public void testMethod(){
// 略
}
2.2.5 @CacheConfig
标记在类上,为整个类的缓存注解提供相同的配置,如:cacheNames、keyGenerator等。
2.3 通过SpEl表达式指定key
使用如下
@Cacheable(cacheNames="user",key="#id")
public User findById(Long id){
// 略
}
2.4 通过key生成器指定key
SpringBoot提供了SimpleKeyGenerator
作为默认的key生成器。下面介绍如何定制并使用key生成器。
- 创建key生成器,实现KeyGenerator接口
public class CustomKeyGenerator implements KeyGenerator {
@Override
public Object generate(Object target, Method method, Object... params){
return Objects.hash(params);
}
}
- 将key生成器注册到Spring容器中
@Configuration
public class Config {
@Bean
public KeyGenerator customKeyGenerator() {
return new CustomKeyGenerator();
}
}
- 配置@Cacheable的keyGeneragor属性
@Cacheable(cacheNames="user",keyGenerator="customKeyGenerator")
public User findById(Long id){
// 略
}
2.5 通过条件表达式设置结果是否缓存
// 方法参数作为条件
@Cacheable(cacheNames="user",condition="#id>0")
public User findById(Long id){
// 略
}
// 方法执行结果作为条件
@Cacheable(cacheNames="user",unless="#result!=0")
public User findById(Long id){
// 略
}
3 SpringBootCache设计原理
通过注解控制缓存是由JSR107规范提出的,但是其提供的注解并不好用,https://github.com/jsr107/jsr107spec/issues/86,可以看看这里。