Spring Boot 에서 Cache 를 적용하는 방법에 대해 알아봅니다.
implementation 'org.springframework.boot:spring-boot-starter-cache'
@Configuration
@RequiredArgsConstructor
@EnableCaching
public class RedisCacheConfig extends CachingConfigurerSupport {
private final RedisConnectionFactory redisConnectionFactory;
@Bean
@Override
public CacheManager cacheManager() {
RedisCacheManagerBuilder builder = RedisCacheManagerBuilder.fromConnectionFactory(redisConnectionFactory);
RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig()
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))
.prefixCacheNameWith("redis-cache:")
.disableCachingNullValues()
.entryTtl(Duration.ofMinutes(10));
builder.cacheDefaults(configuration);
return builder.build();
}
}
Spring Cache 의 주요 기능 및 Annotation 은 다음과 같습니다.
@Cacheable, @CacheEvict 등 캐시 기능을 사용혀려면, @Configuration 클래스에 @EnableCaching Annotation 을 추가하면 됩니다.
@Configuration
@EnableCaching
public class AppConfig {
}
@Cacheable 은 Method 에 Caching 을 적용 할 수 있도록 합니다.
Method의 특정 인자에 대한 결과값(return) 을 Cache 저장소에 저장하고, 동일한 인자값에 대한 요청은 Method 를 실행하지 않고 Cache 저장소에서 반환합니다.
@Cacheable Annotaiton 을 적용 할 때에는 캐시 이름을 지정해주어야 하며, 부여한 이름이 Cache 저장시 정보 구분을 위한 역할로 사용됩니다.
// Example
@Cacheable(cacheNames = "headline", key = "#key")
public Book getHeadline(Test test) { /* ... */}
@Cacheable(cacheNames = "users", condition = "#user.type == 'ADMIN'")
public Book selectUser(User user) { /* ... */}
오래된 캐시 또는 더이상 필요하지 않는 캐시를 삭제합니다.
Cacheable 어노테이션과 마찬가지로 캐시 이름을 넣어주면 메소드가 실행될 때 캐시의 내용이 초기화 됩니다.
@CacheEvict(value = "headline")
public void getHeadline() {
}
만약 해당 메소드의 키값만 삭제하고 싶으면 아래처럼 해줍니다.
@CacheEvict(value = "headline", key = "#test.testNo")
public void getHeadline(Test test) {
}
만약 캐시에 저장된 값을 모두 제거해야 한다면 allEntries 속성을 true로 지정해주면 됩니다.
@CacheEvict(value = "headline", allEntires = true)
public void getHeadline() {
}
캐시의 값을 업데이트(Put) 하는 Method에 Annotation 을 부여하여 사용됩니다.
새로운 캐시의 값 저장만 되며, 캐시 데이터를 읽는 기능은 사용하지 않아, CachePut Annotation 역할이 부여된 Method 를 중복 호출시 매번 Method 내부가 실행되기 때문에 응답 성능 향상이 발생되진 않습니다.
한번에 캐시에 많은 정보를 저장하는 작업(Batch 성 작업 등)에 사용하며, Cacheable Annotation Method 와 구분되어 사용되는 것을 권장합니다.
@CachePut(value = "users, key = "#user.userNo")
public Book putUser(User user) { /* ... */}
같은 타입의 Annotation 을 여러개 묶어줄 때 사용됩니다.
같은 타입의 Annotation 이어야 하며, 서로 다른 타입의 Annotation 사용은 허용되지 않습니다.
@Caching(evict = {
@CacheEvict(value="user", key="#user.no")),
@CacheEvict(value="userGroup", key="#user.groupNo")
})
public void addNewUser(User user) {
insertUserToDB(user);
insertUserGroupToDB(user.getUserGroup());
}
클래스 단위로 캐시 설정을 동일하게 하고 싶을 때 사용합니다.
@CacheConfig(cacheNames={"users"})
-- @CacheConfig(cacheManager = "redisCacheManager")
public class CustomerDataService {
// ...
@Cacheable
public String getAddress(Customer customer) {...}
// ...
}