一、Spring Cache概述
SpringCache定义了 CacheManager 和 Cache 两个接口,但不提供缓存的具体实现。
其他缓存框架,如Ehcache、Caffeine、Redis等,如果需要接入Spring,则需要提供CacheManager和Cache接口的具体实现。
同时,Spring Cache基于AOP实现,于是使用SpringCache只需要在方法上标注相应的注解即可实现。
二、Spring Cache 与 SpringBoot整合
- 第一步,在pom.xml中,添加 spring-boot-starter-cache,以及你所要使用的缓存框架的依赖。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!--这里我整合Caffeine -->
<!-- https://mvnrepository.com/artifact/com.github.ben-manes.caffeine/caffeine -->
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
- 第二步,配置@EnableCaching,开启缓存功能
至此,配置完成。
SpringBoot在启动过程中,会自动创建Caffeine的CacheManager实例。
三、使用Spring Cache
三个最重要的注解:
注解 | 作用 |
---|---|
@Cachable | 执行缓存 |
@CachePut | 更新缓存 |
@CacheEvict | 移除缓存 |
这几个注解标注到方法上,表明要如何处理缓存。
具体见:
package org.otaku.comic.cacheLearn;
import java.util.concurrent.ThreadLocalRandom;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Controller
public class CacheController {
//--------------------------------以方法参数为key--------------------------------
//执行缓存,缓存对象为方法返回值
@Cacheable("cache")
@ResponseBody
@RequestMapping("/getCache")
public String getCache(String p1, String p2) {
log.info("getCache being invoke!");
return "p1 is : " + p1 + ", p2 is : " + p2;
}
//使用方法返回值更新缓存,注意方法参数必须和@Cacheable标注的方法参数一致,才执行更新
@CachePut("cache")
@ResponseBody
@RequestMapping("/updateCache")
public String updateCache(String p1, String p2) {
log.info("updateCache being invoked");
return "p2 is : " + p2 + ",p1 is " + p1;
}
//废弃缓存,方法返回值不做限制,只要方法参数匹配即可
@CacheEvict("cache")
@ResponseBody
@RequestMapping("/evictCache")
public String evictCache(String p1, String p2) {
log.info("evictCache being invoked");
return "evict Success";
}
//有条件的缓存,condition表示条件达成则缓存,unless表示条件达成则不缓存
@Cacheable(value = "name", condition = "#name.length() > 5", unless = "#name.equals('jackey')")
@ResponseBody
@RequestMapping("/getName")
public String getName(String name) {
log.info("getName");
return "getName" + ThreadLocalRandom.current().nextInt(1000000);
}
//---------------------------------自定义key-----------------------------
//使用了lombok框架,自动生成getter和构造函数
@AllArgsConstructor
@Data
public static class User {
private Integer id;
private String username;
private String password;
}
@Cacheable(value = "user", key = "#id")
@ResponseBody
@RequestMapping("/getUser")
public User getUserById(Integer id) {
log.info("getUser");
return new User(id, "user" + id, "pass" + id);
}
//这里,方法参数为User类型,为了让key匹配,指定了字段
@CachePut(value = "user", key = "#user.id")
@ResponseBody
@RequestMapping("/updateUser")
public User updateUser(User user) {
log.info("updateUser");
return user;
}
@CacheEvict(value = "user", key = "#id")
@ResponseBody
@RequestMapping("/evictUser")
public String updateUser(Integer id) {
log.info("evictUser");
return "evict Success";
}
}
四、参考资料
SpringCache详细用法官方文档:
https://docs.spring.io/spring/docs/5.1.5.RELEASE/spring-framework-reference/integration.html#cache
SpringBoot整合SpringCache相关文档:
https://docs.spring.io/spring-boot/docs/2.1.3.RELEASE/reference/htmlsingle/#boot-features-caching