(非常に包括的な)SpringBootカフェインは、ローカルキャッシュを使用します

ディレクトリ

まず、ローカルキャッシュを導入

第二に、カフェインを導入したキャッシュコンポーネント

  1. カフェインのパフォーマンス
  2. カフェインの設定手順
  3. 引用されたソフトと弱参照

三、SpringBootは、2つの方法でカフェインを統合しました

四、SpringBootカフェインを統合する方法

  1. Mavenはその依存関係を導入しました
  2. 設定キャッシュの設定クラス
  3. エンティティオブジェクトのテストを定義します
  4. サービス・インタフェースと実装クラスを定義します。
  5. テストコントローラクラス

五、SpringBootはカフェイン第二の方法を統合しました

  1. Mavenはその依存関係を導入しました
  2. 設定キャッシュの設定クラス
  3. エンティティオブジェクトのテストを定義します
  4. サービス・インタフェースと実装クラスを定義します。
  5. テストコントローラクラス

環境設定:

  • JDKのバージョン:1.8
  • カフェインのバージョン:2.8.0
  • SpringBootバージョン:2.2.2.RELEASE

まず、ローカルキャッシュを導入

それはメモリに、データの読み出し速度が非常に高速ストレージですので、日々の開発で重要な役割を開始するキャッシュ、大幅にデータベースへの圧力を下げる、データベースへのアクセスを減らすことができます。

キャッシュコンポーネントとしてNOSQL Redisの前に導入され、それもコンポーネント間のバッファとしてのキャッシュを分散させることができる複数のサービスを提供するが、消費が増加し、これは、依然として、Redisのネットワークオーバーヘッドを必要とします。ローカルキャッシュはローカルメモリから直接読み取られ、いかなるネットワークのオーバーヘッドは、データキャッシュスパイクシステムなどの少量として、存在しない、リモートキャッシュよりも適切です。

第二に、カフェインを導入したキャッシュコンポーネント

カフェインGithubのドキュメントを記述することで、カフェインは、JAVAベースの高性能キャッシュライブラリー8です。そしてspring5(springboot 2.xの)の後、春には正式にグアバを放棄して、デフォルトのキャッシュコンポーネントとして使用するのカフェインより良いパフォーマンス。

1、カフェインのパフォーマンス

図によって観察することができる。、以下の緩衝成分のカフェインは、最高のパフォーマンスの一つです。

 

2、カフェインの設定手順

 

注意:

  • weakValuesとsoftValuesを同時に使用することはできません。
  • MAXIMUMSIZEとmaximumWeightを同時に使用することはできません。
  • expireAfterWriteに存在する場合expireAfterWriteとexpireAfterAccess同僚が勝ちます。

3、ソフトおよび弱参照は、引用されました

软引用:如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。

弱引用:弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存

 
// 软引用 Caffeine.newBuilder().softValues().build(); // 弱引用 Caffeine.newBuilder().weakKeys().weakValues().build();

三、SpringBoot 集成 Caffeine 两种方式

SpringBoot 有俩种使用 Caffeine 作为缓存的方式:

  • 方式一:直接引入 Caffeine 依赖,然后使用 Caffeine 方法实现缓存。
  • 方式二:引入 Caffeine 和 Spring Cache 依赖,使用 SpringCache 注解方法实现缓存。

下面将介绍下,这俩中集成方式都是如何实现的。

四、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; @Configuration public 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 @ToString public 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 @Service public 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 @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 引入相关依赖

 
<?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()                 // 设置最后一次写入或访问后经过固定时间过期                 .expireAfterAccess(60, TimeUnit.SECONDS)                 // 初始的缓存空间大小                 .initialCapacity(100)                 // 缓存的最大条数                 .maximumSize(1000));         return cacheManager;     } }

3、定义测试的实体对象

 
@Data @ToString public 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 @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";     } }

 

END

发布了202 篇原创文章 · 获赞 41 · 访问量 1万+

おすすめ

転載: blog.csdn.net/Sqdmn/article/details/104451061