最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時(shí)間:2021年01月20日 09:32:28   作者:超級小豆丁  
這篇文章主要介紹了Spring Boot 2.x 把 Guava 干掉了選擇本地緩存之王 Caffeine,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

環(huán)境配置:

  • JDK 版本:1.8
  • Caffeine 版本:2.8.0
  • SpringBoot 版本:2.2.2.RELEASE

一、本地緩存介紹

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

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

二、緩存組件 Caffeine 介紹

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

1、Caffeine 性能

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

2、Caffeine 配置說明

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

注意:

  • weakValuessoftValues 不可以同時(shí)使用。
  • maximumSizemaximumWeight 不可以同時(shí)使用。
  • expireAfterWriteexpireAfterAccess 同事存在時(shí),以 expireAfterWrite 為準(zhǔn)。

3、軟引用與弱引用

  • 軟引用: 如果一個(gè)對象只具有軟引用,則內(nèi)存空間足夠,垃圾回收器就不會(huì)回收它;如果內(nèi)存空間不足了,就會(huì)回收這些對象的內(nèi)存。
  • 弱引用: 弱引用的對象擁有更短暫的生命周期。在垃圾回收器線程掃描它所管轄的內(nèi)存區(qū)域的過程中,一旦發(fā)現(xiàn)了只具有弱引用的對象,不管當(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;

@Configuration
public class CacheConfig {

 @Bean
 public Cache<String, Object> caffeineCache() {
 return Caffeine.newBuilder()
 // 設(shè)置最后一次寫入或訪問后經(jīng)過固定時(shí)間過期
 .expireAfterWrite(60, TimeUnit.SECONDS)
 // 初始的緩存空間大小
 .initialCapacity(100)
 // 緩存的最大條數(shù)
 .maximumSize(1000)
 .build();
 }

}

3、定義測試的實(shí)體對象

import lombok.Data;
import lombok.ToString;

@Data
@ToString
public 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
@Service
public class UserInfoServiceImpl implements UserInfoService {

 /**
 * 模擬數(shù)據(jù)庫存儲(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;
 }
 // 如果緩存中不存在,則從庫中查找
 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());
 }
 // 將新的對象存儲(chǔ),更新舊對象信息
 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
@RequestMapping
public 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 引入相關(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、配置緩存配置類

@Configuration
public class CacheConfig {

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

}

3、定義測試的實(shí)體對象

@Data
@ToString
public 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ù)庫存儲(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());
 }
 // 將新的對象存儲(chǔ),更新舊對象信息
 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
@RequestMapping
public 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/c72fb0c787fc
https://www.cnblogs.com/rickiyang/p/11074158.html
https://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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java 泛型的詳解及實(shí)例

    java 泛型的詳解及實(shí)例

    這篇文章主要介紹了java 泛型的詳解及實(shí)例的相關(guān)資料,希望通過本文大家能徹底掌握泛型的使用方法,需要的朋友可以參考下
    2017-08-08
  • JVM 方法調(diào)用之動(dòng)態(tài)分派(詳解)

    JVM 方法調(diào)用之動(dòng)態(tài)分派(詳解)

    下面小編就為大家?guī)硪黄狫VM 方法調(diào)用之動(dòng)態(tài)分派(詳解)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-05-05
  • java實(shí)現(xiàn)簡單學(xué)生成績管理系統(tǒng)

    java實(shí)現(xiàn)簡單學(xué)生成績管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)簡單學(xué)生成績管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • Java利用Phantomjs實(shí)現(xiàn)生成圖片的功能

    Java利用Phantomjs實(shí)現(xiàn)生成圖片的功能

    這篇文章主要介紹了Java利用Phantomjs實(shí)現(xiàn)生成圖片的功能,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-08-08
  • 養(yǎng)成良好java代碼編碼規(guī)范

    養(yǎng)成良好java代碼編碼規(guī)范

    這篇文章主要介紹了如何養(yǎng)成良好java代碼編碼規(guī)范,規(guī)范需要平時(shí)編碼過程中注意,是一個(gè)慢慢養(yǎng)成的好習(xí)慣,下面小編就帶大家來一起詳細(xì)了解一下吧
    2019-06-06
  • mybatis項(xiàng)目實(shí)現(xiàn)動(dòng)態(tài)表名的三種方法

    mybatis項(xiàng)目實(shí)現(xiàn)動(dòng)態(tài)表名的三種方法

    有時(shí)在開發(fā)過程中java代碼中的表名和數(shù)據(jù)庫的表名并不是一致的,此時(shí)我們就需要?jiǎng)討B(tài)的設(shè)置表名,本文主要介紹了mybatis項(xiàng)目實(shí)現(xiàn)動(dòng)態(tài)表名的三種方法,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-01-01
  • springboot3.4和mybatis plus的版本問題的解決

    springboot3.4和mybatis plus的版本問題的解決

    本文主要介紹了springboot3.4和mybatis plus的版本問題的解決,主要由于Spring Boot 3.4與MyBatis-Plus版本不匹配導(dǎo)致分頁功能問題,下面就來解決這個(gè)問題,感興趣的可以了解一下
    2025-03-03
  • 淺談springMVC接收前端json數(shù)據(jù)的總結(jié)

    淺談springMVC接收前端json數(shù)據(jù)的總結(jié)

    下面小編就為大家分享一篇淺談springMVC接收前端json數(shù)據(jù)的總結(jié),具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-03-03
  • Java之Spring Boot創(chuàng)建和使用

    Java之Spring Boot創(chuàng)建和使用

    Spring 的誕生就是為了簡化 Java 程序的開發(fā)的.Spring Boot 的誕生就是為了簡化 Spring 程序開發(fā)的,對Springboot感興趣的同學(xué)可以借鑒本文
    2023-04-04
  • IntelliJ IDEA設(shè)置代碼的快捷編輯模板Live Templates

    IntelliJ IDEA設(shè)置代碼的快捷編輯模板Live Templates

    今天小編就為大家分享一篇關(guān)于IntelliJ IDEA設(shè)置代碼的快捷編輯模板Live Templates,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2018-10-10

最新評論

江都市| 右玉县| 台江县| 巨鹿县| 丰台区| 新建县| 新沂市| 德阳市| 阳东县| 垦利县| 吉木乃县| 闸北区| 习水县| 南投市| 深水埗区| 祁门县| 平定县| 巴楚县| 南川市| 徐汇区| 措美县| 射洪县| 上犹县| 云林县| 临邑县| 常熟市| 红原县| 广昌县| 长寿区| 佳木斯市| 永和县| 定日县| 滁州市| 华坪县| 多伦县| 泉州市| 黄石市| 香港 | 涪陵区| 吉安市| 舞钢市|