午夜剧场伦理_日本一道高清_国产又黄又硬_91黄色网战_女同久久另类69精品国产_妹妹的朋友在线

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

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

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

環(huán)境配置:

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

緩存在日常開發(fā)中啟動(dòng)至關(guān)重要的作用,由于是存儲(chǔ)在內(nèi)存中,數(shù)據(jù)的讀取速度是非常快的,能大量減少對(duì)數(shù)據(jù)庫(kù)的訪問(wèn),減少數(shù)據(jù)庫(kù)的壓力。

之前介紹過(guò) Redis 這種 NoSql 作為緩存組件,它能夠很好的作為分布式緩存組件提供多個(gè)服務(wù)間的緩存,但是 Redis 這種還是需要網(wǎng)絡(luò)開銷,增加時(shí)耗。本地緩存是直接從本地內(nèi)存中讀取,沒(méi)有網(wǎng)絡(luò)開銷,例如秒殺系統(tǒng)或者數(shù)據(jù)量小的緩存等,比遠(yuǎn)程緩存更合適。

二、緩存組件 Caffeine 介紹

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

1、Caffeine 性能

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

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

2、Caffeine 配置說(shuō)明

參數(shù) 類型 描述 initialCapacity integer 初始的緩存空間大小 maximumSize long 緩存的最大條數(shù) maximumWeight long 緩存的最大權(quán)重 expireAfterAccess duration 最后一次寫入或訪問(wèn)后經(jīng)過(guò)固定時(shí)間過(guò)期 refreshAfterWrite duration 最后一次寫入后經(jīng)過(guò)固定時(shí)間過(guò)期 refreshAfterWrite duration 創(chuàng)建緩存或者最近一次更新緩存后經(jīng)過(guò)固定的時(shí)間間隔,刷新緩存 weakKeys boolean 打開 key 的弱引用 weakValues boolean 打開 value 的弱引用 softValues boolean 打開 value 的軟引用 recordStats - 開發(fā)統(tǒng)計(jì)功能

注意:

weakValues 和 softValues 不可以同時(shí)使用。 maximumSize 和 maximumWeight 不可以同時(shí)使用。 expireAfterWrite 和 expireAfterAccess 同事存在時(shí),以 expireAfterWrite 為準(zhǔn)。3、軟引用與弱引用 軟引用: 如果一個(gè)對(duì)象只具有軟引用,則內(nèi)存空間足夠,垃圾回收器就不會(huì)回收它;如果內(nèi)存空間不足了,就會(huì)回收這些對(duì)象的內(nèi)存。 弱引用: 弱引用的對(duì)象擁有更短暫的生命周期。在垃圾回收器線程掃描它所管轄的內(nèi)存區(qū)域的過(guò)程中,一旦發(fā)現(xiàn)了只具有弱引用的對(duì)象,不管當(dāng)前內(nèi)存空間足夠與否,都會(huì)回收它的內(nèi)存

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

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

方式一: 直接引入 Caffeine 依賴,然后使用 Caffeine 方法實(shí)現(xiàn)緩存。

方式二: 引入 Caffeine 和 Spring Cache 依賴,使用 SpringCache 注解方法實(shí)現(xiàn)緩存。

下面將介紹下,這倆中集成方式都是如何實(shí)現(xiàn)的。

Spring Boot 基礎(chǔ)就不介紹了,推薦看下這個(gè)教程:

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

四、SpringBoot 集成Caffeine 方式一

1、Maven 引入相關(guān)依賴

<?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() // 設(shè)置最后一次寫入或訪問(wèn)后經(jīng)過(guò)固定時(shí)間過(guò)期 .expireAfterWrite(60, TimeUnit.SECONDS) // 初始的緩存空間大小 .initialCapacity(100) // 緩存的最大條數(shù) .maximumSize(1000) .build(); }}

3、定義測(cè)試的實(shí)體對(duì)象

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

4、定義服務(wù)接口類和實(shí)現(xiàn)類

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 { /** * 模擬數(shù)據(jù)庫(kù)存儲(chǔ)數(shù)據(jù) */ 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; } // 如果緩存中不存在,則從庫(kù)中查找 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()); // 替換內(nèi)容 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()); } // 將新的對(duì)象存儲(chǔ),更新舊對(duì)象信息 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、測(cè)試的 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 '沒(méi)有該用戶'; } 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 引入相關(guān)依賴

<?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() // 設(shè)置最后一次寫入或訪問(wèn)后經(jīng)過(guò)固定時(shí)間過(guò)期 .expireAfterAccess(60, TimeUnit.SECONDS) // 初始的緩存空間大小 .initialCapacity(100) // 緩存的最大條數(shù) .maximumSize(1000)); return cacheManager; }}

3、定義測(cè)試的實(shí)體對(duì)象

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

4、定義服務(wù)接口類和實(shí)現(xiàn)類

服務(wù)接口

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);}

服務(wù)實(shí)現(xiàn)類

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 { /** * 模擬數(shù)據(jù)庫(kù)存儲(chǔ)數(shù)據(jù) */ 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()); // 替換內(nèi)容 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()); } // 將新的對(duì)象存儲(chǔ),更新舊對(duì)象信息 userInfoMap.put(oldUserInfo.getId(), oldUserInfo); // 返回新對(duì)象信息 return oldUserInfo; } @Override @CacheEvict(key = '#id') public void deleteById(Integer id) { log.info('delete'); userInfoMap.remove(id); }}

5、測(cè)試的 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 '沒(méi)有該用戶'; } 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

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

標(biāo)簽: Spring
相關(guān)文章:
主站蜘蛛池模板: 欧美乱性| 亚洲一区二区三区在线观看视频 | 夜夜爽夜夜 | 国产精品日韩欧美一区二区三区 | 免费的黄色网 | 青青久在线视频 | 亚洲激情成人 | 精品一区二区在线播放 | 香蕉成人网 | 九九三级 | 手机看av片| 91九色在线视频 | 欧美在线视频一区 | 欧美网站在线观看 | 亚洲美女激情视频 | 玖玖爱在线精品视频 | 自拍偷在线精品自拍偷无码专区 | 亚洲黄色网络 | 亚欧三级| 国产a级片视频 | 日本成人一级片 | 成年人视频在线免费观看 | 精彩毛片 | 国产a免费 | 国产aa视频| 亚洲一区免费观看 | 成年人免费看毛片 | 亚洲激情欧美激情 | 国产精品视频久久久 | 手机看片久久 | 91久久久精品| 国产一区二区三区18 | 日韩视频在线观看一区二区 | 国产com | 色在线观看视频 | aaa一区二区| 日韩精品视 | 中国女人一级一次看片 | 加勒比色综合 | 国产视频大全 | 亚洲大片免费 |