Spring Boot缓存实战 Caffeine示例

作者:xiaolyuh 时间:2021-11-15 17:39:34 

Caffeine和Spring Boot集成

Caffeine是使用Java8对Guava缓存的重写版本,在Spring Boot 2.0中将取代Guava。如果出现Caffeine,CaffeineCacheManager将会自动配置。使用spring.cache.cache-names属性可以在启动时创建缓存,并可以通过以下配置进行自定义(按顺序):

  • spring.cache.caffeine.spec: 定义的特殊缓存

  • com.github.benmanes.caffeine.cache.CaffeineSpec: bean定义

  • com.github.benmanes.caffeine.cache.Caffeine: bean定义

例如,以下配置创建一个foo和bar缓存,最大数量为500,存活时间为10分钟:


spring.cache.cache-names=foo,bar
spring.cache.caffeine.spec=maximumSize=500,expireAfterAccess=600s

除此之外,如果定义了com.github.benmanes.caffeine.cache.CacheLoader,它会自动关联到CaffeineCacheManager。由于该CacheLoader将关联被该缓存管理器管理的所有缓存,所以它必须定义为CacheLoader<Object, Object>,自动配置将忽略所有泛型类型。

引入依赖


<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
 <groupId>com.github.ben-manes.caffeine</groupId>
 <artifactId>caffeine</artifactId>
 <version>2.6.0</version>
</dependency>

开启缓存的支持

使用@EnableCaching注解让Spring Boot开启对缓存的支持


@SpringBootApplication
@EnableCaching// 开启缓存,需要显示的指定
public class SpringBootStudentCacheCaffeineApplication {

public static void main(String[] args) {
   SpringApplication.run(SpringBootStudentCacheCaffeineApplication.class, args);
 }
}

配置文件

新增对缓存的特殊配置,如最大容量、过期时间等


spring.cache.cache-names=people
spring.cache.caffeine.spec=initialCapacity=50,maximumSize=500,expireAfterWrite=10s,refreshAfterWrite=5s

如果使用了refreshAfterWrite配置还必须指定一个CacheLoader,如:


/**
* 必须要指定这个Bean,refreshAfterWrite=5s这个配置属性才生效
*
* @return
*/
@Bean
public CacheLoader<Object, Object> cacheLoader() {
 CacheLoader<Object, Object> cacheLoader = new CacheLoader<Object, Object>() {

@Override
   public Object load(Object key) throws Exception {
     return null;
   }

// 重写这个方法将oldValue值返回回去,进而刷新缓存
   @Override
   public Object reload(Object key, Object oldValue) throws Exception {
     return oldValue;
   }
 };
 return cacheLoader;
}

Caffeine配置说明:

  1. initialCapacity=[integer]: 初始的缓存空间大小

  2. maximumSize=[long]: 缓存的最大条数

  3. maximumWeight=[long]: 缓存的最大权重

  4. expireAfterAccess=[duration]: 最后一次写入或访问后经过固定时间过期

  5. expireAfterWrite=[duration]: 最后一次写入后经过固定时间过期

  6. refreshAfterWrite=[duration]: 创建缓存或者最近一次更新缓存后经过固定的时间间隔,刷新缓存

  7. weakKeys: 打开key的弱引用

  8. weakValues:打开value的弱引用

  9. softValues:打开value的软引用

  10. recordStats:开发统计功能

注意:

  1. expireAfterWrite和expireAfterAccess同事存在时,以expireAfterWrite为准。

  2. maximumSize和maximumWeight不可以同时使用

  3. weakValues和softValues不可以同时使用

示例代码


/**
* @author yuhao.wang
*/
@Service
public class PersonServiceImpl implements PersonService {
 private static final Logger logger = LoggerFactory.getLogger(PersonServiceImpl.class);

@Autowired
 PersonRepository personRepository;

@Override
 @CachePut(value = "people", key = "#person.id")
 public Person save(Person person) {
   Person p = personRepository.save(person);
   logger.info("为id、key为:" + p.getId() + "数据做了缓存");
   return p;
 }

@Override
 @CacheEvict(value = "people")//2
 public void remove(Long id) {
   logger.info("删除了id、key为" + id + "的数据缓存");
   //这里不做实际删除操作
 }

/**
  * Cacheable
  * value:缓存key的前缀。
  * key:缓存key的后缀。
  * sync:设置如果缓存过期是不是只放一个请求去请求数据库,其他请求阻塞,默认是false。
  */
 @Override
 @Cacheable(value = "people", key = "#person.id", sync = true)
 public Person findOne(Person person, String a, String[] b, List<Long> c) {
   Person p = personRepository.findOne(person.getId());
   logger.info("为id、key为:" + p.getId() + "数据做了缓存");
   return p;
 }

@Override
 @Cacheable(value = "people1")//3
 public Person findOne1() {
   Person p = personRepository.findOne(2L);
   logger.info("为id、key为:" + p.getId() + "数据做了缓存");
   return p;
 }

@Override
 @Cacheable(value = "people2")//3
 public Person findOne2(Person person) {
   Person p = personRepository.findOne(person.getId());
   logger.info("为id、key为:" + p.getId() + "数据做了缓存");
   return p;
 }
}

源码:https://github.com/wyh-spring-ecosystem-student/spring-boot-student/tree/releases

来源:https://www.jianshu.com/p/c72fb0c787fc

标签:Spring,Boot,Caffeine
0
投稿

猜你喜欢

  • Android封装MVP实现登录注册功能

    2021-06-14 20:45:08
  • Spring Boot 2.5.0 重新设计的spring.sql.init 配置有啥用

    2021-12-04 00:04:43
  • Android使用criteria选择合适的地理位置服务实现方法

    2022-09-26 14:24:34
  • java实现输入输出流代码分享

    2023-11-18 01:03:45
  • java实现通讯录管理系统

    2021-07-02 00:19:53
  • Spring中BeanFactory FactoryBean和ObjectFactory的三种的区别

    2022-02-21 22:43:58
  • Room Kotlin API的使用入门教程

    2023-11-07 07:06:35
  • Spring Retry 重试实例详解

    2021-07-15 22:43:26
  • Spring Boot实现文件上传下载

    2021-11-22 21:19:36
  • Java基础学习之字符串知识总结

    2021-06-30 10:23:56
  • c# 使用线程对串口serialPort进行收发数据(四种)

    2023-06-20 13:05:48
  • springboot ErrorPageFilter的实际应用详解

    2023-11-24 01:02:59
  • C#使用opencv截取旋转矩形区域图像的实现示例

    2023-11-12 22:20:44
  • 基于c# Task自己动手写个异步IO函数

    2021-08-06 12:07:56
  • c#中Empty()和DefalutIfEmpty()用法分析

    2022-05-20 12:58:55
  • Windows下Flutter+Idea环境搭建及配置

    2022-01-22 18:12:13
  • Spring boot Mybatis 整合(完整版)

    2023-03-28 17:14:32
  • SpringBoot实现Mysql使用MD5进行密码加密的示例

    2022-11-24 23:14:16
  • Java的MD5工具类和客户端测试类

    2022-04-23 03:08:48
  • Servlet实现文件的上传与下载

    2023-08-08 06:13:43
  • asp之家 软件编程 m.aspxhome.com