本文正在参与「金石方案」

前面一篇文章虽然介绍了Caffeine的运用方式,可是更多的是倾向于基础的Caffeine用法;接下来这边博文将给我们介绍一下Caffeine结合Spring的@Cacheable
注解,来完成内部缓存的运用姿势
项目配置
1. 依靠
首先搭建一个标准的SpringBoot项目工程,相关版本以及依靠如下
本项目凭借SpringBoot 2.2.1.RELEASE
+ maven 3.5.3
+ IDEA
进行开发
<dependencies>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
</dependencies>
2. 配置
SpringBoot官方对Caffeine的集成,提供了非常好的支撑,比方本文介绍的在运用 @Cacheable
注解来处理缓存时,咱们无需额定操作,直接在配置文件来完成缓存的指定,以及对应的Caffeine相关配置限定
中心配置如下 application.yml
# 指定全局默认的缓存战略
spring:
cache:
type: caffeine
caffeine:
spec: initialCapacity=10,maximumSize=200,expireAfterWrite=5m
上面的 spring.cache.type 首要用来标明缓存注解的具体缓存完成为 Caffeine,当然还可所以Guava、redis等
其次便是 spring.cache.caffeine.spec
, 它指定了Caffeine的初始化容量巨细,最大个数,失效时间等 (无特殊场景时,一切的缓存注解都是共用这个配置的)
运用实例
1. 开启缓存注解支撑
首先在发动类上增加 @EnableCaching
注解,留意若不加则缓存不会生效
@EnableCaching
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
}
2. 运用实例
咱们界说一个UserService,首要是用来操作用户相关信息,现在先界说一个User
实体类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private Integer uid;
private String uname;
}
然后增加增删查
@Service
// 这个注释的是默认的缓存战略,此时对应的 cacheManager 由 spring.cache.caffeine.spec 来指定缓存规矩
@CacheConfig(cacheNames = "customCache")
public class AnoCacheService {
/**
* 用一个map来模仿存储
*/
private Map<Integer, User> userDb = new ConcurrentHashMap<>();
/**
* 增加数据,并保存到缓存中, 不论缓存中有没有,都会更新缓存
*
* @param user
*/
@CachePut(key = "#user.uid")
public User saveUser(User user) {
userDb.put(user.getUid(), user);
return user;
}
/**
* 优先从缓存中获取数据,若不存在,则从 userDb 中查询,并会将成果写入到缓存中
*
* @param userId
* @return
*/
@Cacheable(key = "#userId")
public User getUser(int userId) {
System.out.println("doGetUser from DB:" + userId);
return userDb.get(userId);
}
@CacheEvict(key = "#userId")
public void removeUser(int userId) {
userDb.remove(userId);
}
}
上面分别介绍了三个注解
- CachePut: 不论缓存有没有,都将办法的回来成果写入缓存中
- Cacheable: 先从缓存查,没有则执行办法,并塞入缓存
- CacheEvit: 失效缓存
其次在类上还有一个@CacheConfig
注解,首要界说了一个 cacheNames
特点,当咱们运用缓存注解时,需求留意的是这个cacheNames必须得有,否则就会报错
当一个类中一切缓存共用一个cacheNames时,能够直接在类上增加@CacheConfig
来避免在每个地方都增加指定
3. 写个测验demo
@RestController
public class TestController {
@Autowired
private AnoCacheService anoCacheService;
private AtomicInteger uid = new AtomicInteger(1);
@RequestMapping(path = "save")
public User save(String name) {
return anoCacheService.saveUser(new User(uid.getAndAdd(1), name));
}
@RequestMapping(path = "query")
public User query(int userId) {
User user = anoCacheService.getUser(userId);
return user == null ? new User() : user;
}
@RequestMapping(path = "remove")
public String remove(int userId) {
anoCacheService.removeUser(userId);
return "ok";
}
}
咱们来实践看一下,第一次没有数据时,回来的是不是空;当有数据之后,缓存是否会命中

4. 小结
这篇博文首要介绍了SpringBoot怎样整合Caffeine,结合Spring的缓存注解,基于能够说是很低本钱的就让咱们的办法完成缓存功用,可是请留意,有几个留意点
- 当我并不期望一切数据共用一个缓存时,怎样处理?
- 比方我有一些要害数据,虽然拜访频率或许没那么高,可是还每次实践读取的本钱很高,又不怎样变动,我期望能够更长久的缓存;
- 假如共用一个缓存,则有或许导致它们被其他的热门数据给挤下线了(超越最大数量限制给删去了)
- 在实践运用时,需求特别留意,加了缓存注解之后,回来的实践上是缓存中的目标,如上面回来的是User目标还好,假如回来的是一个容器,那么直接像这些容器中进行额定的增加、删去元素,是直接影响缓存成果的
别的,检查本文引荐结合下面几篇博文一起享用,以获取更多的知识点
- 【DB系列】缓存注解@Cacheable @CacheEvit @CachePut运用姿势介绍 | 一灰灰Blog
- 【DB系列】SpringBoot缓存注解@Cacheable之自界说key战略及缓存失效时间指定 | 一灰灰Blog
不能错过的源码和相关知识点
0. 项目
- 工程:github.com/liuyueyi/sp…
- 源码:github.com/liuyueyi/sp…
1. 微信大众号: 一灰灰Blog
尽信书则不如,以上内容,纯属一家之言,因个人能力有限,不免有遗漏和过错之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激
下面一灰灰的个人博客,记录一切学习和工作中的博文,欢迎我们前去逛逛
- 一灰灰Blog个人博客 blog.hhui.top
- 一灰灰Blog-Spring专题博客 spring.hhui.top