Java中Caffeine本地緩存項(xiàng)目實(shí)例
前言
為什么需要本地緩存?在系統(tǒng)中,有些數(shù)據(jù),訪問十分頻繁(例如數(shù)據(jù)字典數(shù)據(jù)、國家標(biāo)準(zhǔn)行政區(qū)域數(shù)據(jù)),往往把這些數(shù)據(jù)放入分布式緩存中,但為了減少網(wǎng)絡(luò)傳輸,加快響應(yīng)速度,緩存分布式緩存讀壓力,會(huì)把這些數(shù)據(jù)緩存到本地JVM中,大多是先取本地緩存中,再取分布式緩存中的數(shù)據(jù)
而Caffeine是一個(gè)高性能Java 緩存庫,使用Java8對(duì)Guava緩存重寫版本,在Spring Boot 2.0中將取代Guava。 使用spring.cache.cache-names屬性可以在啟動(dòng)時(shí)創(chuàng)建緩存
例如,以下application配置創(chuàng)建一個(gè)foo和bar緩存,最大數(shù)量為500,存活時(shí)間為10分鐘
spring.cache.cache-names=foo,bar spring.cache.caffeine.spec=initialCapacity=10,maximumSize=500,expireAfterAccess=600s
還有一種代碼實(shí)現(xiàn)方式,我在項(xiàng)目中就是使用代碼方式,如何使用,請(qǐng)往下看
代碼實(shí)現(xiàn)
1.引入依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> <dependency> <groupId>com.github.ben-manes.caffeine</groupId> <artifactId>caffeine</artifactId> <version>2.6.2</version> </dependency>
2.添加一個(gè)CaffeineConfig配置類,開啟緩存@EnableCaching
@Configuration
@EnableCaching //開啟緩存
public class CaffeineConfig {
public static final int DEFAULT_MAXSIZE = 10000;
public static final int DEFAULT_TTL = 600;
/**
* 定義cache名稱、超時(shí)時(shí)長(zhǎng)(秒)、最大容量
* 每個(gè)cache缺?。?0秒超時(shí)、最多緩存50000條數(shù)據(jù),需要修改可以在構(gòu)造方法的參數(shù)中指定。
*/
public enum Caches{
getUserById(600), //有效期600秒
listCustomers(7200,1000), //有效期2個(gè)小時(shí) , 最大容量1000
;
Caches() {
}
Caches(int ttl) {
this.ttl = ttl;
}
Caches(int ttl, int maxSize) {
this.ttl = ttl;
this.maxSize = maxSize;
}
private int maxSize=DEFAULT_MAXSIZE; //最大數(shù)量
private int ttl=DEFAULT_TTL; //過期時(shí)間(秒)
public int getMaxSize() {
return maxSize;
}
public int getTtl() {
return ttl;
}
}
/**
* 創(chuàng)建基于Caffeine的Cache Manager
* @return
*/
@Bean
@Primary
public CacheManager caffeineCacheManager() {
SimpleCacheManager cacheManager = new SimpleCacheManager();
ArrayList<CaffeineCache> caches = new ArrayList<CaffeineCache>();
for(Caches c : Caches.values()){
caches.add(new CaffeineCache(c.name(),
Caffeine.newBuilder().recordStats()
.expireAfterWrite(c.getTtl(), TimeUnit.SECONDS)
.maximumSize(c.getMaxSize())
.build())
);
}
cacheManager.setCaches(caches);
return cacheManager;
}
}3.創(chuàng)建控制器
創(chuàng)建一個(gè)控制器,使用本地緩存,注意@Cacheable,value與上面配置的值對(duì)應(yīng),key為參數(shù),sync=true表示同步,多個(gè)請(qǐng)求會(huì)被阻塞
@RestController
@RequestMapping("cache")
public class CacheController {
@RequestMapping("listCustomers")
@Cacheable( value = "listCustomers" , key = "#length", sync = true)
public List<Customer> listCustomers(Long length){
List<Customer> customers = new ArrayList<>();
for(int i=1; i <= length ; i ++){
Customer customer = new Customer(i, "zhuyu"+i, 20 + i, false);
customers.add(customer);
}
return customers;
}
// 以第一個(gè)參數(shù)為key進(jìn)行緩存
@Cacheable(value="users", key="#p0")
public Long find(Long id) {
return id;
}
// 以User中的id值為key進(jìn)行緩存
@Cacheable(value="users", key="#user.id")
public User find(User user) {
return user;
}
// 以User中的id值為key,且 condition 條件滿足則緩存
@Cacheable(value="users", key="#user.id", condition="#user.id%2==0")
public User find(User user) {
return user;
}
}- @CacheEvict 是用來標(biāo)注清除緩存元素的,可在方法或類上。當(dāng)標(biāo)記在一個(gè)類上表示其中所有的方法的執(zhí)行都會(huì)觸發(fā)緩存的清除操作。
- @CacheEvict可以指定的屬性有value、key、condition、allEntries和beforeInvocation。其中value、key和condition的語義與@Cacheable對(duì)應(yīng)的屬性類似。即value表示清除操作是發(fā)生在哪些Cache上的(對(duì)應(yīng)Cache的名稱);key表示需要清除的是哪個(gè)key,如未指定則會(huì)使用默認(rèn)策略生成的key;condition表示清除操作發(fā)生的條件
// allEntries表示是否需要清除緩存中的所有元素。默認(rèn)為false,當(dāng)allEntries為true時(shí),清除所有的元素
@CacheEvict(value="user", allEntries=true)
public void delete(Integer id) {
System.out.println(id);
}4.啟動(dòng)項(xiàng)目
訪問上面的方法,效果如下,第一次處理時(shí)間為 110ms ,再刷新幾次頁面只要 1ms,說明后面的請(qǐng)求從本地緩存中獲取數(shù)據(jù),并返回了


使用本地緩存可以加快頁面響應(yīng)速度,緩存分布式緩存讀壓力,大量、高并發(fā)請(qǐng)求的網(wǎng)站比較適用
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í)間間隔,刷新緩存
- recordStats:開發(fā)統(tǒng)計(jì)功能
注意:
- expireAfterWrite和expireAfterAccess同時(shí)存在時(shí),以expireAfterWrite為準(zhǔn)。
- maximumSize和maximumWeight不可以同時(shí)使用
到此這篇關(guān)于Java中Caffeine本地緩存項(xiàng)目實(shí)例的文章就介紹到這了,更多相關(guān)Caffeine本地緩存內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
spring boot配置ssl實(shí)現(xiàn)HTTPS的方法
這篇文章主要介紹了spring boot配置ssl實(shí)現(xiàn)HTTPS的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-03-03
springboot項(xiàng)目獲取resources相對(duì)路徑的方法
這篇文章主要介紹了springboot項(xiàng)目獲取resources相對(duì)路徑的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12
Maven?Web項(xiàng)目使用Cargo插件實(shí)現(xiàn)自動(dòng)化部署的詳細(xì)步驟
cargo ,它是一組幫助用戶實(shí)現(xiàn)自動(dòng)化部署,操作Web容器的工具,并且?guī)缀踔С炙械腤eb容器,這篇文章主要介紹了Maven?Web項(xiàng)目使用Cargo實(shí)現(xiàn)自動(dòng)化部署,需要的朋友可以參考下2023-02-02
Java基于Scanner對(duì)象的簡(jiǎn)單輸入計(jì)算功能示例
這篇文章主要介紹了Java基于Scanner對(duì)象的簡(jiǎn)單輸入計(jì)算功能,結(jié)合實(shí)例形式分析了Java使用Scanner對(duì)象獲取用戶輸入半徑值計(jì)算圓形面積功能,需要的朋友可以參考下2018-01-01
Java17新特性之?instanceof運(yùn)算符的實(shí)現(xiàn)
Java17對(duì)??instanceof??運(yùn)算符進(jìn)行了增強(qiáng),引入了模式匹配的功能,本文就來詳細(xì)的介紹一下新特性之instanceof運(yùn)算符的使用,感興趣的可以了解一下2025-10-10
使用Java實(shí)現(xiàn)系統(tǒng)托盤功能的介紹(附源碼以及截圖)
本篇文章介紹了,在Java中實(shí)現(xiàn)系統(tǒng)托盤功能的詳解,文中附源碼以及截圖介紹。需要的朋友參考下2013-05-05
java實(shí)現(xiàn)騰訊ocr圖片識(shí)別接口調(diào)用
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)騰訊ocr圖片識(shí)別接口調(diào)用,拍車牌識(shí)別車牌號(hào)功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-11-11
利用MultipartFile實(shí)現(xiàn)文件上傳功能
這篇文章主要為大家詳細(xì)介紹了利用MultipartFile實(shí)現(xiàn)文件上傳功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11

