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

SpringBoot系列教程之内存Caffeine整合Cachebale注解

前面一篇文章虽然介绍了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";
    }
}

咱们来实践看一下,第一次没有数据时,回来的是不是空;当有数据之后,缓存是否会命中

SpringBoot系列教程之内存Caffeine整合Cachebale注解

4. 小结

这篇博文首要介绍了SpringBoot怎样整合Caffeine,结合Spring的缓存注解,基于能够说是很低本钱的就让咱们的办法完成缓存功用,可是请留意,有几个留意点

  1. 当我并不期望一切数据共用一个缓存时,怎样处理?
  • 比方我有一些要害数据,虽然拜访频率或许没那么高,可是还每次实践读取的本钱很高,又不怎样变动,我期望能够更长久的缓存;
  • 假如共用一个缓存,则有或许导致它们被其他的热门数据给挤下线了(超越最大数量限制给删去了)
  1. 在实践运用时,需求特别留意,加了缓存注解之后,回来的实践上是缓存中的目标,如上面回来的是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
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。