下面我将详细讲解 Spring Boot 2.x 把 Guava 干掉了选择本地缓存之王 Caffeine(推荐)的攻略。
背景
在 Spring Boot 2.x 版本中,默认使用的是 Caffeine 作为本地缓存框架,而在之前的版本中,默认使用的是 Guava,这是因为,Caffeine 有更好的性能和更多的特性。
步骤
下面是使用 Caffeine 缓存的基本步骤:
添加依赖
首先,我们需要添加以下依赖到我们的 pom.xml 文件中:
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>2.8.8</version>
</dependency>
创建缓存
接下来,我们需要创建一个缓存对象:
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
public class CacheDemo {
public static void main(String[] args) {
Cache<String, String> cache = Caffeine.newBuilder()
.maximumSize(100)
.build();
String key = "foo";
String value = "bar";
cache.put(key, value);
System.out.println(cache.getIfPresent(key));
}
}
代码解释:
- 我们使用
Caffeine.newBuilder()
方法来创建一个新的缓存对象; - 我们通过
maximumSize(100)
方法限制了最大元素数量为 100; - 我们通过
build()
方法来构建最终的缓存对象; - 我们使用
put(key, value)
方法将一个键值对存入缓存中; - 我们使用
getIfPresent(key)
方法获取指定键的值。
缓存配置
除了基本的配置以外,Caffeine 还提供了很多其他的配置选项,比如过期时间、刷新时间等等。下面是一个使用了一些配置选项的例子:
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
public class CacheDemo {
public static void main(String[] args) throws Exception {
Cache<String, String> cache = Caffeine.newBuilder()
.expireAfterWrite(1, TimeUnit.MINUTES)
.expireAfterAccess(30, TimeUnit.SECONDS)
.maximumSize(100)
.recordStats()
.build();
String key = "foo";
String value = "bar";
// 缓存未命中时,调用 load 方法获取数据
Function<String, String> loader = k -> value.toUpperCase();
String result = cache.get(key, loader);
System.out.println(result);
// 等待 2 分钟,超时后缓存被清空,所以这里又会调用 loader() 方法
Thread.sleep(TimeUnit.MINUTES.toMillis(2));
result = cache.get(key, loader);
System.out.println(result);
// 输出缓存命中统计信息
System.out.println(cache.stats());
}
}
代码解释:
- 我们使用
expireAfterWrite(1, TimeUnit.MINUTES)
方法来配置缓存条目在写入后留在缓存中的时间; - 我们使用
expireAfterAccess(30, TimeUnit.SECONDS)
方法来配置缓存条目的访问时间; - 我们使用
maximumSize(100)
方法来限制缓存最大元素数量为 100; - 我们使用
recordStats()
方法来记录缓存的统计信息; - 当从缓存中获取数据时,如果缓存未命中,会调用我们定义的
loader
方法来获取数据; - 每次获取数据时,如果数据在缓存中已经过期,则会自动调用
loader
方法来刷新缓存; - 我们使用
cache.stats()
方法来获取缓存的统计信息。
示例
下面是一个使用 Caffeine 缓存的 Spring Boot 示例:
添加依赖
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>2.8.8</version>
</dependency>
缓存配置
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import java.util.concurrent.TimeUnit;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableCaching
public class CacheConfig {
@Bean
public CacheManager cacheManager() {
CaffeineCache helloWorldCache = buildCache("helloWorldCache", 10, 5);
SimpleCacheManager manager = new SimpleCacheManager();
manager.setCaches(List.of(helloWorldCache));
return manager;
}
private CaffeineCache buildCache(String name, int maxSize, int expireAfterAccessInMinutes) {
Cache<Object, Object> cache = Caffeine.newBuilder()
.maximumSize(maxSize)
.expireAfterAccess(expireAfterAccessInMinutes, TimeUnit.MINUTES)
.build();
return new CaffeineCache(name, cache);
}
}
代码解释:
- 我们使用
@EnableCaching
注解开启缓存功能; - 我们通过
cacheManager()
方法创建一个缓存管理器; - 我们通过
buildCache()
方法创建一个缓存对象; - 我们使用
CaffeineCache
类包装我们创建的cache
对象; - 我们根据需要创建多个缓存对象,并将它们存储到
SimpleCacheManager
对象中。
缓存使用
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Autowired
private CacheManager cacheManager;
@Cacheable(cacheNames = "helloWorldCache", key = "#userId")
public String getUserById(String userId) {
// 假装从数据库中获取数据
return "User-" + userId;
}
public void printCacheStats() {
Cache cache = cacheManager.getCache("helloWorldCache");
System.out.println(cache.getNativeCache().stats());
}
}
代码解释:
- 我们通过
@Cacheable
注解将一个方法设置为可缓存的; - 我们使用
cacheNames
属性指定使用的缓存名称; - 我们使用
key
属性指定缓存的键; - 当访问带有
@Cacheable
注解的方法时,会首先检查缓存,如果找到了对应的值,则直接返回,否则调用方法获取数据,并将数据存入缓存中; - 我们可以使用
cacheManager.getCache("helloWorldCache")
方法获取缓存对象,并使用cache.getNativeCache().stats()
方法获取缓存的统计信息。
总结
在 Spring Boot 2.x 版本中,我们推荐使用 Caffeine 作为本地缓存框架。使用 Caffeine 缓存,我们可以非常方便地创建、配置和使用缓存对象。同时,Caffeine 还提供了很多实用的特性,比如过期时间、统计信息等等。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Boot 2.x 把 Guava 干掉了选择本地缓存之王 Caffeine(推荐) - Python技术站