spring cache简介
spring cache是spring提供的一套缓存规则,利用aop实现了非侵入式的缓存功能,可以通过注解很方便的实现接口的缓存。并能够在不更改业务代码情况下更换缓存实现。
spring cache并没有规定缓存实现的具体方式,它提供了接口以供用户进行自定义的实现。用户可以实现本地的缓存,也可实现分布式的缓存。
当然为了进一步为用户提供便利,spring cache自带一些基于本地缓存框架的实现,如ConcurrentMapCache,caffeine等。
spring cache工作流程
从指定的cacheManager中获取指定名称的cache,如果没有指定名称则使用默认的。
检查是否符号缓存条件(condition,unless参数等),是则根据方法签名及参数通过keyGenerator生成key或在指定了key的情况下直接使用指定的key。
得到key后检查指定的缓存cache中是否已经有值,有则直接返回该值,无则执行方法,将方法返回值放入缓存后再返回。
注意多线程情形
spring cache使用
接口及注解介绍
@EnableCaching:开启缓存功能。
@Cacheable:表示方法的结果可以被缓存,调用该方法前,会先检查对应的缓存key在缓存中是否已经有值,如果有就直接返回,不调用方法;如果没有,就会调用方法,同时把结果缓存起来。主要的参数是key,key默认使用方法签名加所有方法参数。可手工指定,可使用SpEL表达式提取参数的一部分。
@CacheEvict:方法被调用时会触发缓存的evict操作,清空缓存中指定key的值。
@CachePut:方法的返回值会被放到缓存中,供其他方法使用,而当前方法自身不会查询缓存。
@CacheConfig:只能加到类上,为类中方法提供一些通用的配置,避免重复代码。这些配置包括 cacheNames、keyGenerator、cacheManager、cacheResolver等。
@Caching:有时单个方法会产生多种缓存操作,比如同时使多个缓存失效等,这时可以使用Caching
指定多个同时生效的操作,支持的操作类型有Cacheable,CachePut,CacheEvict。
Cache接口:提供通用的一些缓存操作。用户可自己实现并注入以替代默认的ConcurrentMapCache。
CacheManager接口:用于获取Cache的接口,应用中允许存在多个具名的Cache以缓存不同模块的内容。主要方法是getCache。
本地缓存使用
引入jar包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
启动类上加注解@EnableCaching
@EnableCaching
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
}
查询方法上加@Cacheable注解,变更方法上加@CacheEvict注解
@Slf4j
@RestController
@RequestMapping("/dictData")
@Api(value = "字典服务",tags = "字典服务")
@CacheConfig(cacheNames = {"dictData"})
public class DictDataController {
private IDictDataService dictDataService;
public DictDataController(IDictDataService dictDataService){
this.dictDataService = dictDataService;
}
@GetMapping("/dictId")
@Cacheable(key = "'dictData'+#id")
public List<VsDictData> getByDictId(String id){
return dictDataService.getByDictId(id);
}
@PatchMapping("/dictId")
@CacheEvict(key = "'dictData'+#id")
public String updateById(String id){
System.out.println("updateById");
return "ok";
}
}
如果要使用其他本地缓存工具,以caffeine为例
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>2.6.2</version>
</dependency>
@Configuration
public class CacheConfig {
@Bean
public CacheManager getCacheManager(){
return new CaffeineCacheManager();
}
}
Redis缓存使用
spring cache的方便之处这里就可以看出,从本地缓存更换为分布式缓存不需要更改任何业务代码。
引入jar包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
增加redis配置(单体redis)
spring:
redis:
host: 192.168.142.142
port: 6379
password: Xjh-redis-0
使用RedisCacheManager。
@Configuration
public class CacheConfig {
@Bean
public CacheManager getCacheManager(@Autowired RedisConnectionFactory connectionFactory){
return RedisCacheManager
.RedisCacheManagerBuilder
.fromConnectionFactory(connectionFactory)
.build();
}
}