成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

您的位置:首頁技術文章
文章詳情頁

Spring Boot 2.x 把 Guava 干掉了選擇本地緩存之王 Caffeine(推薦)

瀏覽:77日期:2023-07-26 10:36:04

環境配置:

JDK 版本:1.8 Caffeine 版本:2.8.0 SpringBoot 版本:2.2.2.RELEASE一、本地緩存介紹

緩存在日常開發中啟動至關重要的作用,由于是存儲在內存中,數據的讀取速度是非常快的,能大量減少對數據庫的訪問,減少數據庫的壓力。

之前介紹過 Redis 這種 NoSql 作為緩存組件,它能夠很好的作為分布式緩存組件提供多個服務間的緩存,但是 Redis 這種還是需要網絡開銷,增加時耗。本地緩存是直接從本地內存中讀取,沒有網絡開銷,例如秒殺系統或者數據量小的緩存等,比遠程緩存更合適。

二、緩存組件 Caffeine 介紹

按 Caffeine Github 文檔描述,Caffeine 是基于 JAVA 8 的高性能緩存庫。并且在 spring5 (springboot 2.x) 后,spring 官方放棄了 Guava,而使用了性能更優秀的 Caffeine 作為默認緩存組件。

1、Caffeine 性能

可以通過下圖觀測到,在下面緩存組件中 Caffeine 性能是其中最好的。

Spring Boot 2.x 把 Guava 干掉了選擇本地緩存之王 Caffeine(推薦)

2、Caffeine 配置說明

參數 類型 描述 initialCapacity integer 初始的緩存空間大小 maximumSize long 緩存的最大條數 maximumWeight long 緩存的最大權重 expireAfterAccess duration 最后一次寫入或訪問后經過固定時間過期 refreshAfterWrite duration 最后一次寫入后經過固定時間過期 refreshAfterWrite duration 創建緩存或者最近一次更新緩存后經過固定的時間間隔,刷新緩存 weakKeys boolean 打開 key 的弱引用 weakValues boolean 打開 value 的弱引用 softValues boolean 打開 value 的軟引用 recordStats - 開發統計功能

注意:

weakValues 和 softValues 不可以同時使用。 maximumSize 和 maximumWeight 不可以同時使用。 expireAfterWrite 和 expireAfterAccess 同事存在時,以 expireAfterWrite 為準。3、軟引用與弱引用 軟引用: 如果一個對象只具有軟引用,則內存空間足夠,垃圾回收器就不會回收它;如果內存空間不足了,就會回收這些對象的內存。 弱引用: 弱引用的對象擁有更短暫的生命周期。在垃圾回收器線程掃描它所管轄的內存區域的過程中,一旦發現了只具有弱引用的對象,不管當前內存空間足夠與否,都會回收它的內存

// 軟引用Caffeine.newBuilder().softValues().build();// 弱引用Caffeine.newBuilder().weakKeys().weakValues().build();三、SpringBoot 集成 Caffeine 兩種方式

SpringBoot 有倆種使用 Caffeine 作為緩存的方式:

方式一: 直接引入 Caffeine 依賴,然后使用 Caffeine 方法實現緩存。

方式二: 引入 Caffeine 和 Spring Cache 依賴,使用 SpringCache 注解方法實現緩存。

下面將介紹下,這倆中集成方式都是如何實現的。

Spring Boot 基礎就不介紹了,推薦看下這個教程:

https://github.com/javastacks/spring-boot-best-practice

四、SpringBoot 集成Caffeine 方式一

1、Maven 引入相關依賴

<?xml version='1.0' encoding='UTF-8'?><project xmlns='http://maven.apache.org/POM/4.0.0' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd'> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.2.RELEASE</version> </parent> <groupId>mydlq.club</groupId> <artifactId>springboot-caffeine-cache-example-1</artifactId> <version>0.0.1</version> <name>springboot-caffeine-cache-example-1</name> <description>Demo project for Spring Boot Cache</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.github.ben-manes.caffeine</groupId> <artifactId>caffeine</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build></project>

2、配置緩存配置類

import com.github.benmanes.caffeine.cache.Cache;import com.github.benmanes.caffeine.cache.Caffeine;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import java.util.concurrent.TimeUnit;@Configurationpublic class CacheConfig { @Bean public Cache<String, Object> caffeineCache() { return Caffeine.newBuilder() // 設置最后一次寫入或訪問后經過固定時間過期 .expireAfterWrite(60, TimeUnit.SECONDS) // 初始的緩存空間大小 .initialCapacity(100) // 緩存的最大條數 .maximumSize(1000) .build(); }}

3、定義測試的實體對象

import lombok.Data;import lombok.ToString;@Data@ToStringpublic class UserInfo { private Integer id; private String name; private String sex; private Integer age;}

4、定義服務接口類和實現類

UserInfoService

import mydlq.club.example.entity.UserInfo;public interface UserInfoService { /** * 增加用戶信息 * * @param userInfo 用戶信息 */ void addUserInfo(UserInfo userInfo); /** * 獲取用戶信息 * * @param id 用戶ID * @return 用戶信息 */ UserInfo getByName(Integer id); /** * 修改用戶信息 * * @param userInfo 用戶信息 * @return 用戶信息 */ UserInfo updateUserInfo(UserInfo userInfo); /** * 刪除用戶信息 * * @param id 用戶ID */ void deleteById(Integer id);}

UserInfoServiceImpl

import com.github.benmanes.caffeine.cache.Cache;import lombok.extern.slf4j.Slf4j;import mydlq.club.example.entity.UserInfo;import mydlq.club.example.service.UserInfoService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.util.StringUtils;import java.util.HashMap;@Slf4j@Servicepublic class UserInfoServiceImpl implements UserInfoService { /** * 模擬數據庫存儲數據 */ private HashMap<Integer, UserInfo> userInfoMap = new HashMap<>(); @Autowired Cache<String, Object> caffeineCache; @Override public void addUserInfo(UserInfo userInfo) { log.info('create'); userInfoMap.put(userInfo.getId(), userInfo); // 加入緩存 caffeineCache.put(String.valueOf(userInfo.getId()),userInfo); } @Override public UserInfo getByName(Integer id) { // 先從緩存讀取 caffeineCache.getIfPresent(id); UserInfo userInfo = (UserInfo) caffeineCache.asMap().get(String.valueOf(id)); if (userInfo != null){ return userInfo; } // 如果緩存中不存在,則從庫中查找 log.info('get'); userInfo = userInfoMap.get(id); // 如果用戶信息不為空,則加入緩存 if (userInfo != null){ caffeineCache.put(String.valueOf(userInfo.getId()),userInfo); } return userInfo; } @Override public UserInfo updateUserInfo(UserInfo userInfo) { log.info('update'); if (!userInfoMap.containsKey(userInfo.getId())) { return null; } // 取舊的值 UserInfo oldUserInfo = userInfoMap.get(userInfo.getId()); // 替換內容 if (!StringUtils.isEmpty(oldUserInfo.getAge())) { oldUserInfo.setAge(userInfo.getAge()); } if (!StringUtils.isEmpty(oldUserInfo.getName())) { oldUserInfo.setName(userInfo.getName()); } if (!StringUtils.isEmpty(oldUserInfo.getSex())) { oldUserInfo.setSex(userInfo.getSex()); } // 將新的對象存儲,更新舊對象信息 userInfoMap.put(oldUserInfo.getId(), oldUserInfo); // 替換緩存中的值 caffeineCache.put(String.valueOf(oldUserInfo.getId()),oldUserInfo); return oldUserInfo; } @Override public void deleteById(Integer id) { log.info('delete'); userInfoMap.remove(id); // 從緩存中刪除 caffeineCache.asMap().remove(String.valueOf(id)); }}

5、測試的 Controller 類

import mydlq.club.example.entity.UserInfo;import mydlq.club.example.service.UserInfoService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;@RestController@RequestMappingpublic class UserInfoController { @Autowired private UserInfoService userInfoService; @GetMapping('/userInfo/{id}') public Object getUserInfo(@PathVariable Integer id) { UserInfo userInfo = userInfoService.getByName(id); if (userInfo == null) { return '沒有該用戶'; } return userInfo; } @PostMapping('/userInfo') public Object createUserInfo(@RequestBody UserInfo userInfo) { userInfoService.addUserInfo(userInfo); return 'SUCCESS'; } @PutMapping('/userInfo') public Object updateUserInfo(@RequestBody UserInfo userInfo) { UserInfo newUserInfo = userInfoService.updateUserInfo(userInfo); if (newUserInfo == null){ return '不存在該用戶'; } return newUserInfo; } @DeleteMapping('/userInfo/{id}') public Object deleteUserInfo(@PathVariable Integer id) { userInfoService.deleteById(id); return 'SUCCESS'; }}五、SpringBoot 集成 Caffeine 方式二

1、Maven 引入相關依賴

<?xml version='1.0' encoding='UTF-8'?><project xmlns='http://maven.apache.org/POM/4.0.0' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd'> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.2.RELEASE</version> </parent> <groupId>mydlq.club</groupId> <artifactId>springboot-caffeine-cache-example-2</artifactId> <version>0.0.1</version> <name>springboot-caffeine-cache-example-2</name> <description>Demo project for Spring Boot caffeine</description> <properties> <java.version>1.8</java.version> </properties> <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> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build></project>

2、配置緩存配置類

@Configurationpublic class CacheConfig { /** * 配置緩存管理器 * * @return 緩存管理器 */ @Bean('caffeineCacheManager') public CacheManager cacheManager() { CaffeineCacheManager cacheManager = new CaffeineCacheManager(); cacheManager.setCaffeine(Caffeine.newBuilder() // 設置最后一次寫入或訪問后經過固定時間過期 .expireAfterAccess(60, TimeUnit.SECONDS) // 初始的緩存空間大小 .initialCapacity(100) // 緩存的最大條數 .maximumSize(1000)); return cacheManager; }}

3、定義測試的實體對象

@Data@ToStringpublic class UserInfo { private Integer id; private String name; private String sex; private Integer age;}

4、定義服務接口類和實現類

服務接口

import mydlq.club.example.entity.UserInfo;public interface UserInfoService { /** * 增加用戶信息 * * @param userInfo 用戶信息 */ void addUserInfo(UserInfo userInfo); /** * 獲取用戶信息 * * @param id 用戶ID * @return 用戶信息 */ UserInfo getByName(Integer id); /** * 修改用戶信息 * * @param userInfo 用戶信息 * @return 用戶信息 */ UserInfo updateUserInfo(UserInfo userInfo); /** * 刪除用戶信息 * * @param id 用戶ID */ void deleteById(Integer id);}

服務實現類

import lombok.extern.slf4j.Slf4j;import mydlq.club.example.entity.UserInfo;import mydlq.club.example.service.UserInfoService;import org.springframework.cache.annotation.CacheConfig;import org.springframework.cache.annotation.CacheEvict;import org.springframework.cache.annotation.CachePut;import org.springframework.cache.annotation.Cacheable;import org.springframework.stereotype.Service;import org.springframework.util.StringUtils;import java.util.HashMap;@Slf4j@Service@CacheConfig(cacheNames = 'caffeineCacheManager')public class UserInfoServiceImpl implements UserInfoService { /** * 模擬數據庫存儲數據 */ private HashMap<Integer, UserInfo> userInfoMap = new HashMap<>(); @Override @CachePut(key = '#userInfo.id') public void addUserInfo(UserInfo userInfo) { log.info('create'); userInfoMap.put(userInfo.getId(), userInfo); } @Override @Cacheable(key = '#id') public UserInfo getByName(Integer id) { log.info('get'); return userInfoMap.get(id); } @Override @CachePut(key = '#userInfo.id') public UserInfo updateUserInfo(UserInfo userInfo) { log.info('update'); if (!userInfoMap.containsKey(userInfo.getId())) { return null; } // 取舊的值 UserInfo oldUserInfo = userInfoMap.get(userInfo.getId()); // 替換內容 if (!StringUtils.isEmpty(oldUserInfo.getAge())) { oldUserInfo.setAge(userInfo.getAge()); } if (!StringUtils.isEmpty(oldUserInfo.getName())) { oldUserInfo.setName(userInfo.getName()); } if (!StringUtils.isEmpty(oldUserInfo.getSex())) { oldUserInfo.setSex(userInfo.getSex()); } // 將新的對象存儲,更新舊對象信息 userInfoMap.put(oldUserInfo.getId(), oldUserInfo); // 返回新對象信息 return oldUserInfo; } @Override @CacheEvict(key = '#id') public void deleteById(Integer id) { log.info('delete'); userInfoMap.remove(id); }}

5、測試的 Controller 類

import mydlq.club.example.entity.UserInfo;import mydlq.club.example.service.UserInfoService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;@RestController@RequestMappingpublic class UserInfoController { @Autowired private UserInfoService userInfoService; @GetMapping('/userInfo/{id}') public Object getUserInfo(@PathVariable Integer id) { UserInfo userInfo = userInfoService.getByName(id); if (userInfo == null) { return '沒有該用戶'; } return userInfo; } @PostMapping('/userInfo') public Object createUserInfo(@RequestBody UserInfo userInfo) { userInfoService.addUserInfo(userInfo); return 'SUCCESS'; } @PutMapping('/userInfo') public Object updateUserInfo(@RequestBody UserInfo userInfo) { UserInfo newUserInfo = userInfoService.updateUserInfo(userInfo); if (newUserInfo == null){ return '不存在該用戶'; } return newUserInfo; } @DeleteMapping('/userInfo/{id}') public Object deleteUserInfo(@PathVariable Integer id) { userInfoService.deleteById(id); return 'SUCCESS'; }}

參考地址:

https://www.jianshu.com/p/c72fb0c787fchttps://www.cnblogs.com/rickiyang/p/11074158.htmlhttps://github.com/my-dlq/blog-example/tree/master/springboot/springboot-caffeine-cache-example

到此這篇關于Spring Boot 2.x 把 Guava 干掉了選擇本地緩存之王 Caffeine的文章就介紹到這了,更多相關Spring Boot 2.x Caffeine內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Spring
相關文章:
成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久
亚洲无线码一区二区三区| 国产午夜亚洲精品理论片色戒| 91久久精品一区二区三| 国产精品毛片久久久久久| 成人福利电影精品一区二区在线观看| 欧美色视频在线观看| 婷婷综合五月天| 国产欧美在线| 综合久久久久久久| 欧美特黄a级高清免费大片a级| 精品国产乱码久久久久久1区2区 | 激情综合色播五月| 久久久久综合| 三级成人在线视频| 亚洲区欧美区| **欧美大码日韩| 亚洲国产日韩综合一区| 国产精品乱码久久久久久| 暖暖成人免费视频| 国产亚洲视频系列| 欧美99久久| 日本一区二区综合亚洲| 欧美91福利在线观看| 国产人伦精品一区二区| 欧美在线黄色| 国产精品美女久久久久久| 国产精品www994| 国产精品理论片在线观看| 好吊日精品视频| 国产精品乱人伦中文| 激情久久中文字幕| 中文字幕一区二区5566日韩| 亚洲成色www久久网站| 亚洲人成网站影音先锋播放| 一区二区三区精品视频在线观看| 亚洲黄色小说网站| 欧美亚洲色图校园春色| 日韩成人av影视| 欧美日韩色综合| 国产精品一区二区三区网站| 欧美成人女星排名| 91视频国产观看| 国产精品高潮呻吟久久| 国产日韩高清一区二区三区在线| 亚洲图片欧美色图| 日本丰满少妇一区二区三区| 激情国产一区二区| 精品日韩av一区二区| 色综合中文综合网| 欧美日韩精品福利| 国产激情精品久久久第一区二区 | 亚洲激情中文1区| 久久国产主播| 狠狠色丁香久久婷婷综| 日韩欧美国产综合| 午夜国产一区| 一区二区三区成人| 在线国产亚洲欧美| 粉嫩aⅴ一区二区三区四区五区 | 国产精品美女久久久久久久久| 夜夜精品视频| 免费的国产精品| 欧美精品免费视频| 欧美呦呦网站| 曰韩精品一区二区| 欧美日韩一二三区| av在线综合网| 亚洲少妇最新在线视频| 久久蜜桃资源一区二区老牛| 国产乱人伦精品一区二区在线观看| 久久午夜羞羞影院免费观看| 夜久久久久久| 国产在线精品一区在线观看麻豆| 精品国产一区二区三区av性色| 好吊日精品视频| 日韩av成人高清| 久久中文字幕电影| 欧美三区不卡| 亚洲高清视频中文字幕| 欧美精品免费视频| 亚洲午夜久久久久久尤物| 日韩av在线播放中文字幕| 欧美一区二区成人6969| 国产字幕视频一区二区| 秋霞午夜av一区二区三区| 精品免费国产二区三区| 亚洲二区三区四区| 久久不见久久见中文字幕免费| 久久久久99精品国产片| 老鸭窝91久久精品色噜噜导演| 国产成人在线免费| 亚洲三级理论片| 色激情天天射综合网| www.亚洲在线| 亚洲成人精品一区二区| 精品欧美一区二区久久| 国产女主播一区二区| 懂色av噜噜一区二区三区av| 一区二区三区资源| 日韩欧美在线1卡| 亚洲欧美视频| 99久久免费视频.com| 三级久久三级久久| 中文字幕va一区二区三区| 欧洲人成人精品| 欧美韩国一区| 麻豆国产欧美一区二区三区| 国产欧美精品一区| 欧美在线影院一区二区| 伊人久久亚洲热| 国产91精品露脸国语对白| 亚洲一区二区三区视频在线播放| 久久综合色之久久综合| 久久伊人一区二区| 午夜久久tv| 精品在线播放午夜| 亚洲人亚洲人成电影网站色| 在线播放欧美女士性生活| 国产亚洲精久久久久久| 欧美日本韩国一区| 尤物在线精品| 成人理论电影网| 亚洲国产日韩一级| 国产精品少妇自拍| 欧美日韩一级片在线观看| 日韩午夜黄色| 99这里都是精品| 久久99九九99精品| 亚洲黄色av一区| 国产欧美日韩精品在线| 正在播放亚洲一区| 免费看亚洲片| 欧美jizzhd精品欧美巨大免费| 国产专区欧美精品| 亚欧色一区w666天堂| 国产精品欧美一级免费| 日韩一区二区三区电影| 老司机久久99久久精品播放免费| 国产在线成人| 粉嫩aⅴ一区二区三区四区| 日韩国产欧美在线播放| 一区二区三区在线观看视频| 久久精品视频网| 日韩欧美国产1| 欧美巨大另类极品videosbest| 免播放器亚洲| 国产日韩1区| 亚洲高清免费| 91在线视频网址| 国产精品1024久久| 日韩精品免费视频人成| 亚洲综合视频在线| 国产精品久久久久影院| 久久夜色精品国产噜噜av| 91精品国产综合久久婷婷香蕉| 欧美在线看片a免费观看| 久久精品99| 国产一区二区久久久| 狠狠爱成人网| 欧美不卡一区| 色综合天天综合色综合av | 久久久久久久久久久99999| 欧美一区二区三区小说| 在线精品视频一区二区三四 | 欧美在线看片| 成人精品视频网站| 国产尤物一区二区| 久久国产精品免费| 蜜臂av日日欢夜夜爽一区| 午夜视频一区二区| 亚洲成va人在线观看| 亚洲影院理伦片| 一区二区三区日韩在线观看| 自拍偷拍亚洲综合| 综合在线观看色| ●精品国产综合乱码久久久久| 国产色爱av资源综合区| 久久中文娱乐网| 久久久久久久久久久久电影| 久久综合999| 国产午夜精品久久久久久免费视 | 日韩1区2区3区| 午夜精品久久久久久久久久| 亚洲国产欧美日韩另类综合| 亚洲一区二区三区自拍| 亚洲激情校园春色| 亚洲综合一二三区| 一区二区三区四区亚洲| 亚洲精品美国一| 亚洲一区二区三区小说| 日韩精品三区四区| 美腿丝袜在线亚洲一区| 精品系列免费在线观看| 国产一区二区三区在线观看免费视频| 国产一区二区三区久久悠悠色av| 国产精品亚洲一区二区三区在线 | 精品国产一二三| 欧美精品一区二区三区在线播放| 久久女同互慰一区二区三区| 久久品道一品道久久精品|