Spring Boot 2.x 는 Guava 를 제거 하고 로 컬 캐 시 를 선택 한 왕 Caffine(추천)
JDK 버 전:1.8
캐 시 는 일상적인 개발 에서 중요 한 역할 을 합 니 다.메모리 에 저장 되 어 있 기 때문에 데이터 의 읽 기 속 도 는 매우 빠 르 고 데이터 베이스 에 대한 접근 을 대량으로 줄 이 며 데이터 베이스 의 압력 을 줄 일 수 있 습 니 다.
이전에 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
-
통계 기능 을 개발 하 다
주의:
weakValues
과 softValues
은 동시에 사용 할 수 없습니다.maximumSize
과 maximumWeight
은 동시에 사용 할 수 없습니다.expireAfterWrite
과 expireAfterAccess
동료 가 존재 할 때 는 expireAfterWrite
을 기준 으로 한다.
//
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 방식 21.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 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 저 를 많이 사랑 해 주세요!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[MeU] Hashtag 기능 개발➡️ 기존 Tag 테이블에 존재하지 않는 해시태그라면 Tag , tagPostMapping 테이블에 모두 추가 ➡️ 기존에 존재하는 해시태그라면, tagPostMapping 테이블에만 추가 이후에 개발할 태그 기반 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.