亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

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

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

瀏覽:13日期: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
相關文章:
主站蜘蛛池模板: 国产无卡一级毛片aaa | 欧美高清激情毛片 | 特黄特色一级特色大片中文 | 国内精品91最新在线观看 | 国产精品亚洲欧美日韩区 | 黄网站色视频免费看无下截 | a成人在线| 国产一区二区三区免费视频 | 最近中文日本字幕免费完整 | 91免费在线播放 | 在线观看成人免费 | 91资源在线视频 | 国产在线观看的 | 免费看国产一级特黄aa大片 | 免费影院在线观看 | 成人黄色免费观看 | 日韩一区二区视频在线观看 | 午夜三级在线 | 日本无卡αv免费视频 | 国产a久久精品一区二区三区 | 国产在线拍国产拍拍偷 | 色婷婷基地 | 欧美一级www毛片 | 91极品视频在线观看 | 成人蜜桃视频网站网址 | 国产精品久久天天影视 | 国产又色又爽黄的网站免费 | 91在线一区二区三区 | 日韩在线操 | 蜜桃臀久久伊人福利 | 久草资源免费 | 国产男女性特黄录像 | 日本高清高色 | 中文线码中文高清播放中 | 五月天激激婷婷大综合丁香 | 四虎91视频 | 国产成人刺激视频在线观看 | 国产一区二区三区免费 | 色片免费| jiucao在线观看精品 | 欧美亚洲在线观看 |