最近了解到本地缓存有比Google开发的Guava效率更高的Caffeine,所以有了本篇文章
简单来使用了解一下Caffeine
github官方地址:https://github.com/ben-manes/caffeine/
环境配置:
- JDK:1.8
- Caffeine 版本:2.8.6
- springboot版本:2.4.0
1. Caffeine 性能图
2. Caffeine 配置说明
参数 | 类型 | 描述 |
---|---|---|
initialCapacity | integer | 初始的缓存空间大小 |
maximumSize | long | 缓存的最大条数 |
maxmumWeight | long | 缓存的最大权重 |
expireAfterAccess | duration | 最后一次写入或访问后经过固定时间过期 |
expireAfterWrite | duration | 最后一次写入后经过固定时间过期 |
refreshAfterWrite | duration | 写入后经过固定的时间刷新缓存 |
weakKeys | boolean | 打开key的弱引用 |
weakValues | boolean | 打开value的弱引用 |
softValues | boolean | 打开value的软引用 |
recordStats | - | 统计功能 |
2.1注意点
weakValues
和softValues
软弱引用不可以同时使用。maximumSize
和maximumWeight
不可以同时使用。expireAfterWrite
和expireAfterAccess
同时存在时,以expireAfterWrite
为准
3. 软引用与弱引用
- 软引用:如果一个对象为软引用,如果内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。
- 弱引用:弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存
- 虚引用和强引用这篇文章先不说
4. springboot集成Caffeine
4.1 pom 引入Caffeine依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.miao.redis</groupId>
<artifactId>springboot-caffeine-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springboot-caffeine-demo</name>
<description>Demo project for Spring Boot Cache</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!--spring-mvc-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.3.3.RELEASE</version>
</dependency>
<!-- caffeine 本地缓存 -->
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>2.8.6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
4.2 缓存配置类CacheConfig
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.TimeUnit;
/**
* @author by miao
* spring boot cache config
*/
@Configuration
public class CacheConfig {
@Bean
public Cache<String, Object> creatCaffeineCache() {
return Caffeine.newBuilder()
//设置最后一次写入或访问后经过固定时间过期
.expireAfterWrite(60, TimeUnit.SECONDS)
//初始化缓存空间大小
.initialCapacity(100)
//最大缓存数
.maximumSize(1000)
.build();
}
}
4.3定义结构体User
/**
* @author miao
*/
public class User {
private String id;
private String userName;
private String password;
private Integer age;
private Integer sex;
@Override
public String toString() {
return "User{" +
"id=" + id +
", userName='" + userName + '\'' +
", password='" + password + '\'' +
", age=" + age +
", sex=" + sex +
'}';
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Integer getSex() {
return sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
}
4.4 定义Controller、Service、ServiceImpl
-
TestController
import cn.miao.service.UserService; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; /** * @author miao */ @RestController public class TestController { @Resource private UserService userService; @PostMapping("/user") public String saveToDb(@RequestBody User user) { return userService.save(user); } @GetMapping("/user") public User getUserInfo(@RequestParam("userId") String userId) { return userService.getUserInfo(userId); } }
-
UserService
/**
* @author by miao
*/
public interface UserService {
String save(User user);
User getUserInfo(String userId);
}
- UserServiceImpl
import com.github.benmanes.caffeine.cache.Cache;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
/**
* @author miao
*/
@Service
public class UserServiceImpl implements UserService {
@Resource
private Cache<String, Object> caffeineCache;
@Override
@Transactional(rollbackFor = Exception.class)
public String save(User user) {
//todo 存储到数据库中
caffeineCache.asMap().put(user.getId(), user);
return "Success to save user ";
}
@Override
public User getUserInfo(String userId) {
User userInfo = (User) caffeineCache.asMap().get(userId);
if (null == userInfo) {
//todo 从数据库中查询正确的数据并放入缓存中
}
return userInfo;
}
}
4.5 使用PostMan测试接口
{
"id":"1",
"userName":"testName",
"password":"123456",
"age":"18",
"sex":"1"
}