본문 바로가기
dev/spring

Spring Boot Application Caching

by igooo 2024. 6. 24.
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에 대해서는 캐시 라이브러리에서 지원하지 않을 수 있다.

 

 

참고