Spring Cache简介
在很多频繁调用方法的场景,假如我们不需要每次调用的方法都是实时更新的,此时可以使用缓存机制。缓存实现方式有很多种,可以使用redis、本地内存缓存、各种Cache框架。而在SpringBoot框架中,天然支持Spring Cache的使用,且接入尤为简单。
Spring Cache的简单原理
依赖于Spring Bean的切面机制来实现缓存,针对每个@CacheConfig的方法进行切面织入,在实际调用前先进行缓存查询。注解切面简介
Spring Cache缺陷:
- 使用缓存的类必须是Bean,否则无法注入切面。
- 必须是不同Bean之间的方法调用,否则无法触发切面。规避方法
Spring Cache使用方法
- 引入Spring Cache依赖
- 使用@EnableCaching 注解开启缓存功能
- 在需要缓存的方法上使用@CacheConfig 定义缓存配置
引入Spring Cache依赖
1 | <dependency> |
开启缓存功能
在SpringBoot的主类上增加注解@EnableCaching
1 | @SpringBootApplication |
缓存配置
在需要使用缓存的方法上进行缓存配置。
例如频繁调用方法A的场景下,希望每次调用前先进行缓存查找,没有缓存情况下再进行实际调用。
1 | @Cacheable(value = "getProduct", key = "#deviceType + '_' + #manufacturerId + '_' + #model + '_' + #protocolType") |
配置说明
| value | 必填 | 缓存的命名空间 |
| key | 可选 | 指定一个唯一的key(在缓存命名空间中),使用SpEL表达式 |
| condition | 可选 | 限定条件,哪种情况使用缓存,使用SpEL表达式 |
| unless | 可选 | 限定条件,哪种情况下不使用缓存,使用SpEL表达式 |
配置无效原因
有时候会发现配置了缓存之后并没有生效,以下是在实际使用过程中发现的可能原因,供参考。
服务类内部方法调用并不触发缓存动作
因为Spring Cache基于切面,所以内部方法调用由于不会调用切面,导致缓存不生效。规避方法
如下示例缓存不生效1
2
3
4
5
6
7
8
9
10
11public class test {
@Cacheable
public void A() {
return;
}
public void B() {
A();
}
}
方法未在接口中定义
Spring把实现类装载成为Bean的时候,会用代理包装一下,所以从Spring Bean的角度看,只有接口里面的方法是可见的,其它的都隐藏了,自然课看不到实现类里面的非接口方法,@Cacheable不起作用。规避方法