SpringBoot에서 Redis를 활용하여 Cache를 적용하는 방법을 알아본다. 보통 로컬 Cache를 적용할 때 Caffeine Cache 또는 Ehcache를 적용할 수 있는데 글로벌 Cache로 Redis도 쉽게 적용이 가능하다.
1. 의존성 설정
redis 적용을 위해서 'spring-boot-starter-data-redis' 의존성을 추가해준다.
implementation 'org.springframework.boot:spring-boot-starter-data-redis:3.1.0'
2. Config 설정
application.yml 이나 application.properties 파일에 아래와 같이 redis 설정을 진행한다. 필자는 properties 파일 기준으로 작성을 했다.
# redis
spring.cache.type=redis
spring.data.redis.host=localhost
spring.data.redis.port=6379
spring.data.redis.password=
spring.data.redis.repositories.enabled=false
expire.defaultTime=600
다음으로 Config 파일을 아래와 같이 작성해준다. 제일 상단에 @EnableCaching 어노테이션을 설정하는 것과, 하단에 RedisCacheManager 빈을 등록해주는 것이 중요하다.
@EnableCaching
@Configuration
public class RedisConfig {
@Value("${spring.data.redis.host}")
private String redisHost;
@Value("${spring.data.redis.port}")
private int redisPort;
@Value("${spring.data.redis.password}")
private String redisPwd;
@Value("${expire.defaultTime}")
private long defaultExpireSecond;
@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); // timestamp 설정 제거
mapper.registerModules(new JavaTimeModule(), new Jdk8Module()); // java8, java time module 등록
return mapper;
}
@Bean
public RedisConnectionFactory redisConnectionFactory() {
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
redisStandaloneConfiguration.setPort(redisPort);
redisStandaloneConfiguration.setHostName(redisHost);
redisStandaloneConfiguration.setPassword(redisPwd);
LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(redisStandaloneConfiguration);
return lettuceConnectionFactory;
}
@Bean
public RedisCacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory,
ObjectMapper objectMapper) {
RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig()
.disableCachingNullValues() // null 허용 제거
.entryTtl(Duration.ofSeconds(defaultExpireSecond))
.serializeKeysWith(RedisSerializationContext
.SerializationPair
.fromSerializer(new StringRedisSerializer())).serializeValuesWith(RedisSerializationContext.SerializationPair
.fromSerializer(new GenericJackson2JsonRedisSerializer(objectMapper)));
return RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(redisConnectionFactory)
.cacheDefaults(configuration).build();
}
}
3. Cache 적용
Service 클래스에서 Cache를 적용할 메소드에 @Cacheable 어노테이션을 작성해준다.
@Service
@Slf4j
@RequiredArgsConstructor
public class PostSearchServiceImpl {
private final PostSearchMapper postSearchMapper;
@Cacheable(value = "getProducts", key = "'getProducts-' + #postSearchRequest.getId()")
public List<PostDTO> getProducts(PostSearchRequest postSearchRequest) {
List<PostDTO> postDTOList = null;
try {
postDTOList = postSearchMapper.selectPosts(postSearchRequest);
log.info("call method getProducts!!, {}", postDTOList); // Redis 적용 테스트용 로그
} catch (RuntimeException e) {
e.printStackTrace();
}
return postDTOList;
}
}
Cache 삭제 테스트를 위해서 다른 메소드에는 @CacheEvict 어노테이션을 아래와 같이 작성해준다.
@CacheEvict(value = "getProducts", allEntries = true)
public void register(String id) {
log.info("cache evict!!")
}
4. 테스트
먼저 Cache 적용(@Cacheable)을 테스트 해보면 메소드가 처음 호출될 때는 아래와 같이 로그가 최초에 한번 찍히게 되고, 두번째 호출부터는 Cache가 적용되어(메소드 내부가 호출되지 않음) 해당 로그가 찍히지 않게 되는 것을 확인할 수 있다.
그리고 Redis를 조회해보면 아래와 같이 Cache값이 저장된 것을 확인할 수 있다.
이제 Cache를 삭제하는(@CacheEvict) 메소드를 호출하게 되면 Cache가 제거되고, 위의 Cache 적용 메소드를 다시 호출하면 메소드가 호출되어 로그가 다시 찍히게 된다.
'개발 > SpringBoot' 카테고리의 다른 글
Invalid value type for attribute 'factoryBeanObjectType': java.lang.String 에러 해결 (1) | 2024.10.09 |
---|---|
SpringBoot3 CircuitBreaker Resilience4j 알아보기 (1) | 2023.10.08 |
SpringBoot AWS S3 한글명 파일업로드 에러 (0) | 2023.08.20 |
Gradle build jar 시 plain(xxxx-plain.jar) 제거하기 (0) | 2023.07.22 |
springdoc swagger ui disable Petstore(swagger-ui enabled false not working) (0) | 2023.06.19 |
댓글