久久福利_99r_国产日韩在线视频_直接看av的网站_中文欧美日韩_久久一

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

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

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

環(huán)境配置:

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

緩存在日常開(kāi)發(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ò)開(kāi)銷(xiāo),增加時(shí)耗。本地緩存是直接從本地內(nèi)存中讀取,沒(méi)有網(wǎng)絡(luò)開(kāi)銷(xiāo),例如秒殺系統(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ù) 類(lèi)型 描述 initialCapacity integer 初始的緩存空間大小 maximumSize long 緩存的最大條數(shù) maximumWeight long 緩存的最大權(quán)重 expireAfterAccess duration 最后一次寫(xiě)入或訪問(wèn)后經(jīng)過(guò)固定時(shí)間過(guò)期 refreshAfterWrite duration 最后一次寫(xiě)入后經(jīng)過(guò)固定時(shí)間過(guò)期 refreshAfterWrite duration 創(chuàng)建緩存或者最近一次更新緩存后經(jīng)過(guò)固定的時(shí)間間隔,刷新緩存 weakKeys boolean 打開(kāi) key 的弱引用 weakValues boolean 打開(kāi) value 的弱引用 softValues boolean 打開(kāi) value 的軟引用 recordStats - 開(kāi)發(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 依賴(lài),然后使用 Caffeine 方法實(shí)現(xiàn)緩存。

方式二: 引入 Caffeine 和 Spring Cache 依賴(lài),使用 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)依賴(lài)

<?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、配置緩存配置類(lèi)

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è)置最后一次寫(xiě)入或訪問(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ù)接口類(lèi)和實(shí)現(xiàn)類(lèi)

UserInfoService

import mydlq.club.example.entity.UserInfo;public interface UserInfoService { /** * 增加用戶(hù)信息 * * @param userInfo 用戶(hù)信息 */ void addUserInfo(UserInfo userInfo); /** * 獲取用戶(hù)信息 * * @param id 用戶(hù)ID * @return 用戶(hù)信息 */ UserInfo getByName(Integer id); /** * 修改用戶(hù)信息 * * @param userInfo 用戶(hù)信息 * @return 用戶(hù)信息 */ UserInfo updateUserInfo(UserInfo userInfo); /** * 刪除用戶(hù)信息 * * @param id 用戶(hù)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); // 如果用戶(hù)信息不為空,則加入緩存 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 類(lèi)

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)有該用戶(hù)'; } 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 '不存在該用戶(hù)'; } return newUserInfo; } @DeleteMapping('/userInfo/{id}') public Object deleteUserInfo(@PathVariable Integer id) { userInfoService.deleteById(id); return 'SUCCESS'; }}五、SpringBoot 集成 Caffeine 方式二

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

<?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、配置緩存配置類(lèi)

@Configurationpublic class CacheConfig { /** * 配置緩存管理器 * * @return 緩存管理器 */ @Bean('caffeineCacheManager') public CacheManager cacheManager() { CaffeineCacheManager cacheManager = new CaffeineCacheManager(); cacheManager.setCaffeine(Caffeine.newBuilder() // 設(shè)置最后一次寫(xiě)入或訪問(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ù)接口類(lèi)和實(shí)現(xiàn)類(lèi)

服務(wù)接口

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

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

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 類(lèi)

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)有該用戶(hù)'; } 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 '不存在該用戶(hù)'; } 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)文章:
主站蜘蛛池模板: 亚洲国产成人在线 | 狠狠插狠狠操 | 久久久久国产精品 | 日本亚洲欧美 | 亚洲激情视频在线观看 | 日韩www | 国产片久久| porn在线| 激情小说综合网 | 97久久精品人人做人人爽50路 | 日韩一区中文字幕 | 精品日韩一区 | 黄瓜av| 综合久久综合久久 | 国产精品爱久久久久久久 | 不卡的免费av | 一区二区蜜桃 | 91人人 | 色玖玖| 成人一区电影 | 91精品国产综合久久久蜜臀粉嫩 | 日韩a级免费视频 | 亚洲高清在线视频 | 天天操妹子 | 日韩中文字幕a | 欧美精品99 | 色综合欧美 | 天天澡天天狠天天天做 | 日韩精品免费看 | 亚洲一区视频在线 | 国产精品久久久久久亚洲调教 | 免费av观看| 999精品视频 | 亚洲高清视频在线 | 亚洲精品一区二区三区蜜桃久 | 日韩精品av一区二区三区 | 亚洲精品视频免费看 | 黄网站免费在线 | 亚洲一区免费观看 | 亚洲 欧美 日韩 精品 | 久国产精品|