这是我参与更文挑战的第13天,活动详情查看: 更文挑战。
今天,我们来基于
Spring boot
框架应用集成使用号称史上最强的Java
堆内缓存框架Caffeine
。它的官网是这样说的Caffeine is a high performance, near optimal caching library,是的,毫不客气!自夸为高性能,近乎最优的缓存库。
一、为什么是它?
为啥它这么自信,因为Caffeine
它是Google
借助于Java 8
,在GuavaCache
的基础上进行了一次相当全面的优化升级。升级了哪些内容呢,内容很多,不一一赘述,只划重点。那就是提供了更加丰富的缓存过期策略,特别是基于 Google
工程师Window TinyLfu 回收策略,提供了一个近乎最佳的命中率。因其优秀的性能,Spring 5
果断放弃了Guava
,敞开怀抱拥抱了Caffeine
。
二、工程实践
俗话说的好,先学会如何使用工具,再研究如何创造工具。本篇文章暂不深入如此优秀的Caffeine
,有机会再写深度写一篇。那我们就来基于Spring boot
+ Java 8
简单使用它。
2.1依赖项
只需要引入两个依赖,分别是spring-boot-starter-cache
,caffeine
,版本号按照各自工程需要自行配置。
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> <version>2.3.8.RELEASE</version> </dependency> <dependency> <groupId>com.github.ben-manes.caffeine</groupId> <artifactId>caffeine</artifactId> <version>2.8.8</version> </dependency> </dependencies>
2.2开发过程
开发基于SpringBoot
的自动装配。
首先写一个配置文件OrderCaffeineProperties
``` @ConfigurationProperties(prefix = "me.caffeine.order") @Getter @Setter public class OrderCaffeineProperties {
private String name = "order";
private int initSize = 10;
private int maxSize = 1000;
private Duration expireTime = Duration.ofMinutes(10);
} ```
这个配置文件比较简单,主要是为了配置缓存的初始化大小、最大的存储范围、过期时间,用于初始化缓存的时候使用。
接下来是配置类OrderCaffeineAutoConfigure
``` @EnableConfigurationProperties(OrderCaffeineProperties.class) @Configuration public class OrderCaffeineAutoConfigure {
@Bean
@ConditionalOnMissingBean(
name = {"orderCache"}
)
public Cache<Long, BigDecimal> orderCache(OrderCaffeineProperties properties) {
return Caffeine.newBuilder()
.initialCapacity(properties.getInitSize())
.maximumSize(properties.getMaxSize())
.expireAfterWrite(properties.getExpireTime().getSeconds(), TimeUnit.SECONDS)
.build();
}
} ```
在配置类里,根据配置文件的参数实例化了一个简单的缓存bean
,托付于容器管理。
然后在工程的Resources/META-INF
目录下配置自动装配的文件。即添加一个spring.factories
文件。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ me.stone.training.platform.spring4all.caffeine.autoconfigure.OrderCaffeineAutoConfigure
2.3测试过程
这次测试偷了一个懒,直接在测试目录新建立一个应用启动类Launcher
,观察缓存失效的过程。
``` @SpringBootApplication @Slf4j public class Launcher {
@SneakyThrows
public static void main(String[] args) {
final ConfigurableApplicationContext ctx = SpringApplication.run(Launcher.class, args);
final Cache<Long, BigDecimal> orderCache = (Cache<Long, BigDecimal>) ctx.getBean("orderCache", new TypeReference<Cache<Long, BigDecimal>>() {});
orderCache.put(1L,BigDecimal.valueOf(100));
orderCache.put(2L,BigDecimal.valueOf(200));
log.info("start...");
orderCache.asMap().forEach((k,v)-> log.info("key is {},and value is {}",k,v));
TimeUnit.SECONDS.sleep(30);
log.info("sleep 30s");
orderCache.asMap().forEach((k,v)-> log.info("key is {},and value is {}",k,v));
TimeUnit.SECONDS.sleep(40);
log.info("sleep 70s");
orderCache.asMap().forEach((k,v)-> log.info(" key is {},and value is {}",k,v));
ctx.close();
}
} ```
工程的配置文件application.yml
内容如下
me: caffeine: order: expire-time: 70s init-size: 10 max-size: 1000 name: order
配置的内容为缓存在建立后70s失效,缓存的初始化大小为10,最大范围为1000。
启动应用类以后,执行的结果如下
在意料之中,因为配置的缓存是70s,缓存建立后30秒,缓存未失效,所以缓存的内容还在;缓存建立后70s,缓存已经失效,所以缓存的内容已经被清除。
2.4源码地址
附上Github
的源代码地址 training.platform.spring4all.caffeine