Spring?Cache?集成?Caffeine實(shí)現(xiàn)項(xiàng)目緩存的示例
一、前言
Spring Cache本身是Spring框架中一個(gè)緩存體系的抽象實(shí)現(xiàn),本身不具備緩存能力,需要配合具體的緩存實(shí)現(xiàn)來完成,如Ehcache、Caffeine、Guava、Redis等。
二、緩存注解
- @EnableCaching:開啟緩存功能
- @Cacheable:定義緩存,用于觸發(fā)緩存
- @CachePut:定義更新緩存,觸發(fā)緩存更新
- @CacheEvict:定義清楚緩存,觸發(fā)緩存清除
- @Caching:組合定義多種緩存功能
- @CacheConfig:定義公共設(shè)置,位于class之上
三、實(shí)戰(zhàn)操作
我選擇使用目前最受歡迎的Caffeine來作為具體的緩存實(shí)現(xiàn)方式,下面是一個(gè)demo:
1、依賴引入
<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-cache</artifactId>
</dependency>
2、yaml配置
spring:
cache:
cache-names: USER
caffeine:
spec: initialCapacity=50,maximumSize=500,expireAfterWrite=5s
type: caffeine
Caffeine配置說明
- initialCapacity=[integer]: 初始的緩存空間大小
- maximumSize=[long]: 緩存的最大條數(shù)
- maximumWeight=[long]: 緩存的最大權(quán)重
- expireAfterAccess=[duration]: 最后一次寫入或訪問后經(jīng)過固定時(shí)間過期
- expireAfterWrite=[duration]: 最后一次寫入后經(jīng)過固定時(shí)間過期
- refreshAfterWrite=[duration]: 創(chuàng)建緩存或者最近一次更新緩存后經(jīng)過固定的時(shí)間間隔,刷新緩存
- weakKeys: 打開key的弱引用
- weakValues:打開value的弱引用
- softValues:打開value的軟引用
- recordStats:開發(fā)統(tǒng)計(jì)功能
注意
- expireAfterWrite和expireAfterAccess同事存在時(shí),以expireAfterWrite為準(zhǔn)。
- maximumSize和maximumWeight不可以同時(shí)使用
- weakValues和softValues不可以同時(shí)使用
3、開啟緩存

4、模擬方法
service層
@Service
@Slf4j
public class CaffeineService {
public static Map<String, String> map = new HashMap<>();
static {
map.put("1", "zhangsan");
map.put("2", "lisi");
map.put("3", "wangwu");
}
@Cacheable(value = "USER", key = "#id")
public String getUser(String id) {
log.info("getUser() run......");
return map.get(id);
}
@CachePut(value = "USER", key = "#id")
public String updateUser(String id, String name) {
log.info("updateUser() run......");
map.put(id, name);
return map.toString();
}
@CacheEvict(value = "USER", key = "#id")
public String delUser(String id) {
log.info("delUser() run......");
map.remove(id);
return map.toString();
}
}
controller層
@RestController
@RequestMapping("/cache")
@Slf4j
public class CaffeineController {
@Autowired
private CaffeineService caffeineService;
@GetMapping("/user/{id}")
public String getUser(@PathVariable String id) {
long start = System.currentTimeMillis();
String res = caffeineService.getUser(id);
long end = System.currentTimeMillis();
log.info("查詢耗時(shí):" + (end - start));
return res;
}
@GetMapping("/user/{id}/{name}")
public String updateUser(@PathVariable String id, @PathVariable String name) {
return caffeineService.updateUser(id, name);
}
@DeleteMapping("/user/{id}")
public String delUser(@PathVariable String id) {
return caffeineService.delUser(id);
}
}
5、測(cè)試
第一次查詢:

第二次查詢:

查詢耗時(shí)明顯小于第一次查詢,因?yàn)榈诙沃苯臃祷鼐彺?,速度提升?/p>
執(zhí)行更新后再查詢:
會(huì)使緩存失效。會(huì)重新執(zhí)行查詢方法查詢

執(zhí)行刪除后再查詢:
會(huì)使緩存失效。會(huì)重新執(zhí)行查詢方法查詢

6、改造
上述通過yaml文件配置的方式不夠靈活,無法實(shí)現(xiàn)多種緩存策略,所以現(xiàn)在一般使用javaconfig的形式進(jìn)行配置。
下面是示例代碼:
@Configuration
public class CaffeineConfig {
@Bean
public CacheManager caffeineCacheManager() {
SimpleCacheManager simpleCacheManager = new SimpleCacheManager();
List<CaffeineCache> caffeineCaches = new ArrayList<>();
for (CacheType cacheType : CacheType.values()) {
caffeineCaches.add(new CaffeineCache(cacheType.name(),
Caffeine.newBuilder()
.expireAfterWrite(cacheType.getExpires(), TimeUnit.SECONDS)
.build()));
}
simpleCacheManager.setCaches(caffeineCaches);
return simpleCacheManager;
}
}
public enum CacheType {
USER(5),
TENANT(20);
private int expires;
CacheType(int expires) {
this.expires = expires;
}
public int getExpires() {
return expires;
}
}
這樣我們就能對(duì)USER設(shè)置5秒消防時(shí)間,對(duì)TENANT設(shè)置20秒消亡時(shí)間,在實(shí)際項(xiàng)目中這種方式更加的靈活。
到此這篇關(guān)于Spring Cache 集成 Caffeine實(shí)現(xiàn)項(xiàng)目緩存的示例的文章就介紹到這了,更多相關(guān)Spring Cache Caffeine緩存內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring?@DateTimeFormat日期格式化時(shí)注解場(chǎng)景分析
這篇文章主要介紹了Spring?@DateTimeFormat日期格式化時(shí)注解場(chǎng)景分析,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-05-05
SpringBoot中使用JWT的實(shí)戰(zhàn)
本文主要介紹了SpringBoot中使用JWT的實(shí)戰(zhàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06
idea一招搞定同步所有配置(導(dǎo)入或?qū)С鏊信渲?
使用intellij idea很長(zhǎng)一段時(shí)間,軟件相關(guān)的配置也都按照自己習(xí)慣的設(shè)置好,如果需要重裝軟件,還得需要重新設(shè)置,本文就詳細(xì)的介紹了idea 同步所有配置,感興趣的可以了解一下2021-07-07
springboot接入netty實(shí)現(xiàn)在線統(tǒng)計(jì)人數(shù)
本文主要介紹了springboot接入netty實(shí)現(xiàn)在線統(tǒng)計(jì)人數(shù),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-03-03
MyBatis實(shí)現(xiàn)簡(jiǎn)單的數(shù)據(jù)表分月存儲(chǔ)
本文主要介紹了MyBatis實(shí)現(xiàn)簡(jiǎn)單的數(shù)據(jù)表分月存儲(chǔ),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03
SpringBoot環(huán)境屬性占位符解析和類型轉(zhuǎn)換方式
這篇文章主要介紹了SpringBoot環(huán)境屬性占位符解析和類型轉(zhuǎn)換方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11
Java設(shè)計(jì)模式之裝飾模式(Decorator模式)介紹
這篇文章主要介紹了Java設(shè)計(jì)模式之裝飾模式(Decorator模式)介紹,本文講解了為什么使用Decorator、如何使用裝飾模式、Jive中的Decorator實(shí)現(xiàn)等內(nèi)容,需要的朋友可以參考下2015-03-03

