728x90
간단한 예제로 Spring Boot Application에서 캐쉬를 구현할 때 어떻게 사용해야하는지 살펴본다.
Implement
build.gradle
plugins {
id 'java'
id 'org.springframework.boot' version '3.3.1'
id 'io.spring.dependency-management' version '1.1.5'
}
group = 'org.igooo'
version = '0.0.1-SNAPSHOT'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
tasks.named('test') {
useJUnitPlatform()
}
Application.class
@SpringBootApplication
@EnableCaching
public class CacheApplication {
public static void main(String[] args) {
SpringApplication.run(CacheApplication.class, args);
}
}
UserService.class
@Service
@CacheConfig(cacheNames = "user_cache")
class UserService {
private ConcurrentHashMap<Integer, User> userRepository = new ConcurrentHashMap<>();
@CachePut(key = "#root.args[0].id")
User create(User user) {
this.userRepository.put(user.getId(), user);
return user;
}
@Cacheable(key = "#root.args[0]")
User findById(Integer id) {
return this.userRepository.get(id);
}
@CacheEvict(allEntries = true)
void deleteAll() {
this.userRepository.clear();
}
}
Declarative Annotation-based Caching
- @Cacheable: key에 해당하는 값이 이미 캐시에 있는 경우 메서드를 실행하지 않고 리턴한다. Optional 반환 유형은 자동으로 언래핑되고, Optional 값이 없으면 null이 저장된다.
- @CacheEvict: 캐시에서 요소를 제거한다.
- @CachePut: 메서드 실행을 방해하지 않고(항상 호출) 메서드의 리턴값이 캐시된다. 리턴값으로 void로 선언되면 아무것도 저장하지 않는다.
- @Caching: 메서드에 적용할 여러 새키 작업을 다시 그룹화한다.
- @CacheConfig: 클래스 수준에서 일반적인 캐시 관련 설정을 공유한다. 위 예제에서는 user_cache라는 이름으로 캐시를 만들었다.
고려사항
- @Cacheable을 주로 사용하여 데이터를 캐시 했지만 @CachePut을 사용하여 데이터 변경 시점에 바로 cache를 적용할 수 있다.
- sync 속성 : 다중 스레드 환경에서 동일한 key에 대해 특정 작업이 동시에 호출 가능하다.(서버 시작 시점에 동일한 키에 cache 요청) 기본 옵션은 여러 cache 요청에 대하여 여러 번 계산되어 불필요한 cahce 작업이 될 수 있다.(cahce 등록도 비싼 작업)
- sync 옵션을 활성화 하는 경우 하나의 스레드만 캐시로 처리하고 다른 스레드는 block 시킬 수 있다. (성능 저하에 영향은 가겠지만 자주 변경되지 않는 값이라면 적용할만하다.)
- sync에 대해서는 캐시 라이브러리에서 지원하지 않을 수 있다.
참고
'dev > spring' 카테고리의 다른 글
[Spring] Springdoc-openapi 사용하여 API 문서 만들기 (0) | 2024.07.16 |
---|---|
Kubernetes에서 Spring @Scheduled 사용하기 (0) | 2024.07.09 |
Spring - Modulith - Working with Applicaton Events (0) | 2024.06.21 |
[Spring Framework 6.2] Support for fallback beans (0) | 2024.06.15 |
[Spring Framework 6.2] Bean Background Initialization (0) | 2024.06.13 |