Caffeine 借鉴了 Google Guava 开发的一款缓存插件,提供了近乎最佳命中率的高性能的缓存库。Caffeine 缓存与 ConcurrentMap 的核心差异在于,Caffeine 会自动驱逐元素以控制内存,而 ConcurrentMap 需手动移除。LoadingCache 和AsyncLoadingCache 的自动加载特性在特定场景下尤为有用。
而 Caffeine 在 SpringBoot Cache 中也有很好的兼容性,SpringBoot Cache 可以通过 Caffeine 来实现本地缓存,也可以通过 SpringBootCache 的 CacheManager 来实现 Redis 和 Caffeine 的二级缓存功能。
今天先说怎么实现一个最简单的 Caffeine 缓存。 我这里是使用 SpringBoot 3.x 作为我测试的版本。所以需要的 JDK17以上才能运行。 可以从 IDEA 中新建项目也可以从 springstart 来创建。
然后展示一下我引入的关键 dependency
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
在项目中新建一个 config 目录,并添加一个 CacheConfiguration 类 。
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.TimeUnit;
/**
* 本地缓存
*/
@Configuration
// 这里是开启缓存的注解
@EnableCaching
public class CacheConfiguration {
/**
* 本地缓存
*
* @param caffeine
* @return
*/
@Bean(name = "onlyLocalCacheManager")
public CacheManager onlyLocalCacheManager(Caffeine<Object, Object> caffeine) {
CaffeineCacheManager caffeineCacheManager = new CaffeineCacheManager();
caffeineCacheManager.setCaffeine(caffeine);
return caffeineCacheManager;
}
@Bean
public Caffeine<Object, Object> caffeineConfig() {
return Caffeine.newBuilder().expireAfterWrite(60, TimeUnit.MINUTES);
}
}
定义一个实体类 User
用来返回内容
import lombok.Getter;
import lombok.Setter;
import java.io.Serial;
import java.io.Serializable;
@Getter
@Setter
public class User implements Serializable {
@Serial
private static final long serialVersionUID = -4727730251923802865L;
private String name;
}
上面这些配置完成之后就可以实现 Caffeine 缓存功能了,现在就可以在服务层来使用 @Cacheable
、@CachePut
、@CacheEvict
等注解来调用 Caffeine 了。 这时候需要再写一个 UserController
控制器来通过 PostMan 访问,就大功告成了。
import com.runbrick.entity.User;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
/**
* 存到了 caffeine 中
*
* @param userName 用户名
* @return
*/
@GetMapping("user/cache/local/info")
@Cacheable(cacheManager = "onlyLocalCacheManager", value = "userInfo", key = "#userName")
public User userInfoCacheByLocal(@RequestParam("userName") String userName) {
User user = new User();
user.setName(userName);
return user;
}
}
这里代码我只实现了 Cacheable 其他的和这个是一样的。这样访问这个地址的时候第一次会将我查询的用户名称放入本地缓存中,第二次直接从缓存中读取。
注:
[1] Caffeine 项目开源地址:[[https://github.com/ben-manes/caffeine]]
[2] maven 地址:[[https://central.sonatype.com/artifact/com.github.ben-manes.caffeine/caffeine]]
[3] Spring start 地址:[[https://start.spring.io/]]
评论区