SpringBoot中使用Spring Cache(一)

Spring Cache简介

在很多频繁调用方法的场景,假如我们不需要每次调用的方法都是实时更新的,此时可以使用缓存机制。缓存实现方式有很多种,可以使用redis、本地内存缓存、各种Cache框架。而在SpringBoot框架中,天然支持Spring Cache的使用,且接入尤为简单。

Spring Cache的简单原理

依赖于Spring Bean的切面机制来实现缓存,针对每个@CacheConfig的方法进行切面织入,在实际调用前先进行缓存查询。注解切面简介

Spring Cache缺陷:

  • 使用缓存的类必须是Bean,否则无法注入切面。
  • 必须是不同Bean之间的方法调用,否则无法触发切面。规避方法

Spring Cache使用方法

  1. 引入Spring Cache依赖
  2. 使用@EnableCaching 注解开启缓存功能
  3. 在需要缓存的方法上使用@CacheConfig 定义缓存配置

引入Spring Cache依赖

1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>

开启缓存功能

在SpringBoot的主类上增加注解@EnableCaching

1
2
3
4
5
@SpringBootApplication
@EnableCaching
public class IoAppBuilderApplication {
SpringApplication.run(Application.class, args);
}

缓存配置

在需要使用缓存的方法上进行缓存配置。
例如频繁调用方法A的场景下,希望每次调用前先进行缓存查找,没有缓存情况下再进行实际调用。

1
2
3
4
@Cacheable(value = "getProduct", key = "#deviceType + '_' + #manufacturerId + '_' + #model + '_' + #protocolType")
public ProductDTO getProduct(String appId, String deviceType, String manufacturerId, String model, String protocolType) {
/***/
}

配置说明

| value | 必填 | 缓存的命名空间 |
| key | 可选 | 指定一个唯一的key(在缓存命名空间中),使用SpEL表达式 |
| condition | 可选 | 限定条件,哪种情况使用缓存,使用SpEL表达式 |
| unless | 可选 | 限定条件,哪种情况下不使用缓存,使用SpEL表达式 |

配置参考

配置无效原因

有时候会发现配置了缓存之后并没有生效,以下是在实际使用过程中发现的可能原因,供参考。

服务类内部方法调用并不触发缓存动作

因为Spring Cache基于切面,所以内部方法调用由于不会调用切面,导致缓存不生效。规避方法

如下示例缓存不生效

1
2
3
4
5
6
7
8
9
10
11
public class test {

@Cacheable
public void A() {
return;
}

public void B() {
A();
}
}

方法未在接口中定义

Spring把实现类装载成为Bean的时候,会用代理包装一下,所以从Spring Bean的角度看,只有接口里面的方法是可见的,其它的都隐藏了,自然课看不到实现类里面的非接口方法,@Cacheable不起作用。规避方法