Spring Boot 2.x 는 Guava 를 제거 하고 로 컬 캐 시 를 선택 한 왕 Caffine(추천)

환경 설정:
JDK 버 전:1.8
  • Caffine 버 전:2.8.0
  • SpringBoot 버 전:2.2.2.RELEASE
  • 로 컬 캐 시 소개
    캐 시 는 일상적인 개발 에서 중요 한 역할 을 합 니 다.메모리 에 저장 되 어 있 기 때문에 데이터 의 읽 기 속 도 는 매우 빠 르 고 데이터 베이스 에 대한 접근 을 대량으로 줄 이 며 데이터 베이스 의 압력 을 줄 일 수 있 습 니 다.
    이전에 Redis 라 는 NoSql 을 캐 시 구성 요소 로 소개 한 적 이 있 습 니 다.분포 식 캐 시 구성 요소 로 여러 서비스 간 의 캐 시 를 제공 할 수 있 지만 Redis 는 네트워크 비용 이 필요 하고 시간 소 모 를 증가 해 야 합 니 다.로 컬 캐 시 는 로 컬 메모리 에서 직접 읽 습 니 다.네트워크 비용 이 없습니다.예 를 들 어 스 톱 시스템 이나 데이터 양 이 적은 캐 시 등 은 원 격 캐 시 보다 더 적합 합 니 다.
    2.캐 시 구성 요소 Caffine 소개
    Caffine Github 문서 에 따 르 면 Caffine 은 JAVA 8 기반 고성능 캐 시 라 이브 러 리 입 니 다.또한 spring 5(spring boot 2.x)이후 spring 은 공식 적 으로 Guava 를 포기 하고 성능 이 좋 은 Caffine 을 기본 캐 시 구성 요소 로 사용 했다.
    1.카페인 성능
    아래 캐 시 구성 요소 중 Caffine 성능 이 가장 좋 은 것 으로 다음 그림 을 통 해 관측 할 수 있 습 니 다.

    2、Caffine 설정 설명
    매개 변수
    유형
    묘사 하 다.
    initialCapacity
    integer
    초기 캐 시 공간 크기
    maximumSize
    long
    캐 시 최대 개수
    maximumWeight
    long
    캐 시 최대 가중치
    expireAfterAccess
    duration
    마지막 기록 이나 방문 후 고정 시간 이 지나 면 만 료 됩 니 다.
    refreshAfterWrite
    duration
    마지막 기록 후 고정 시간 이 지나 면 만 료 됩 니 다.
    refreshAfterWrite
    duration
    캐 시 를 만 들 거나 최근 에 캐 시 를 업데이트 한 후 고정된 시간 간격 을 거 쳐 캐 시 를 새로 고 칩 니 다.
    weakKeys
    boolean
    키 의 약 한 인용 열기
    weakValues
    boolean
    value 의 약 한 인용 열기
    softValues
    boolean
    value 의 소프트 인용 열기
    recordStats
    -
    통계 기능 을 개발 하 다
    주의:
  • weakValuessoftValues 은 동시에 사용 할 수 없습니다.
  • maximumSizemaximumWeight 은 동시에 사용 할 수 없습니다.
  • expireAfterWriteexpireAfterAccess 동료 가 존재 할 때 는 expireAfterWrite 을 기준 으로 한다.
  • 3.소프트 인용 과 약 인용
  • 소프트 인용:한 대상 이 소프트 인용 만 있 으 면 메모리 공간 이 충분 하고 쓰레기 회수 기 는 회수 하지 않 습 니 다.메모리 공간 이 부족 하면 대상 의 메모 리 를 회수 합 니 다.
  • 약 인용:약 인용 대상 은 더 짧 은 생명 주 기 를 가진다.쓰레기 회수 기 스 레 드 가 관할 하 는 메모리 영역 을 스 캔 하 는 과정 에서 약 한 인용 대상 만 발견 되면 현재 메모리 공간 이 충분 하 든 그렇지 않 든 메모리
  • 을 회수 합 니 다.
    
    //    
    Caffeine.newBuilder().softValues().build();
    
    //    
    Caffeine.newBuilder().weakKeys().weakValues().build();
    3.SpringBoot 통합 Caffine 두 가지 방식
    SpringBoot 는 Caffine 을 캐 시 로 사용 하 는 두 가지 방식 이 있 습 니 다.
    방식 1:Caffine 의존 도 를 직접 도입 한 후 Caffine 방법 으로 캐 시 를 실현 합 니 다.
    방식 2:Caffine 과 Spring Cache 의존 을 도입 하고 SpringCache 주석 방법 으로 캐 시 를 실현 합 니 다.
    이 두 가지 집적 방식 이 어떻게 실현 되 었 는 지 소개 한다.
    Spring Boot 기 초 는 소개 하지 않 겠 습 니 다.이 튜 토리 얼 을 추천 합 니 다.
    https://github.com/javastacks/spring-boot-best-practice
    4.SpringBoot 통합 Caffine 방식 1
    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";
     }
    
    }
    5.SpringBoot 통합 Caffine 방식 2
    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";
     }
    
    }
    참고 주소:
    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
    여기 서 Spring Boot 2.x 는 Guava 를 제거 하고 로 컬 캐 시 를 선택 한 왕 Caffine 에 관 한 글 을 소개 합 니 다.더 많은 Spring Boot 2.x Caffine 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 저 를 많이 사랑 해 주세요!

    좋은 웹페이지 즐겨찾기