Skip to content

Commit cbb2e96

Browse files
authored
Merge pull request #86 from Block-Guard/refactor/add-redis
[Refactor] Redis 추가
2 parents 635fe3f + 59ad3d5 commit cbb2e96

File tree

8 files changed

+69
-2
lines changed

8 files changed

+69
-2
lines changed

build.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ dependencies {
3030
implementation 'org.springframework.boot:spring-boot-starter-actuator'
3131
implementation 'org.springframework.boot:spring-boot-starter-mail'
3232

33+
implementation 'org.springframework.boot:spring-boot-starter'
34+
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
35+
implementation 'com.fasterxml.jackson.core:jackson-databind'
36+
3337
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.7.0'
3438
implementation 'org.springframework.boot:spring-boot-starter-validation'
3539
compileOnly 'org.projectlombok:lombok'

src/main/java/com/blockguard/server/domain/admin/api/AdminApi.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import lombok.RequiredArgsConstructor;
1414
import lombok.extern.slf4j.Slf4j;
1515
import org.springframework.beans.factory.annotation.Value;
16+
import org.springframework.cache.annotation.CacheEvict;
1617
import org.springframework.web.bind.annotation.PostMapping;
1718
import org.springframework.web.bind.annotation.RequestMapping;
1819
import org.springframework.web.bind.annotation.RequestParam;

src/main/java/com/blockguard/server/domain/news/application/NewsService.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import com.blockguard.server.global.exception.BusinessExceptionHandler;
1111
import lombok.AllArgsConstructor;
1212
import lombok.extern.slf4j.Slf4j;
13+
import org.springframework.cache.annotation.Cacheable;
1314
import org.springframework.data.domain.Page;
1415
import org.springframework.data.domain.PageRequest;
1516
import org.springframework.data.domain.Pageable;
@@ -24,6 +25,7 @@
2425
public class NewsService {
2526
private final NewsRepository newsRepository;
2627

28+
@Cacheable(value = "news:list:v2", key = "'list:' + #page + ':' + #size + ':' + #sort + ':' + #category")
2729
public NewsPageResponse getNewsList(int page, int size, String sort, String category) {
2830
Pageable pageable = PageRequest.of(page - 1, size, getSort(sort));
2931
Page<NewsArticle> newsPage;

src/main/java/com/blockguard/server/domain/news/dto/response/NewsArticleResponse.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@
44
import lombok.AllArgsConstructor;
55
import lombok.Builder;
66
import lombok.Getter;
7+
import lombok.NoArgsConstructor;
78

89
import java.time.Duration;
910
import java.time.LocalDateTime;
1011

1112
@Getter
1213
@Builder(toBuilder = true)
1314
@AllArgsConstructor
15+
@NoArgsConstructor
1416
public class NewsArticleResponse {
1517
private Long id;
1618
private String title;

src/main/java/com/blockguard/server/domain/news/dto/response/NewsPageResponse.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
import lombok.AllArgsConstructor;
44
import lombok.Builder;
55
import lombok.Getter;
6+
import lombok.NoArgsConstructor;
67

78
import java.util.List;
89

910
@Getter
1011
@Builder
1112
@AllArgsConstructor
13+
@NoArgsConstructor
1214
public class NewsPageResponse {
1315
private List<NewsArticleResponse> news;
1416
private PageableInfo pageableInfo;

src/main/java/com/blockguard/server/domain/news/dto/response/PageableInfo.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
import lombok.AllArgsConstructor;
44
import lombok.Builder;
55
import lombok.Getter;
6+
import lombok.NoArgsConstructor;
67

78
@Getter
89
@AllArgsConstructor
10+
@NoArgsConstructor
911
@Builder
1012
public class PageableInfo {
1113
private int page;

src/main/java/com/blockguard/server/domain/news/scheduler/NewsSaveScheduler.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.blockguard.server.infra.crawler.DaumNewsCrawler;
55
import lombok.RequiredArgsConstructor;
66
import lombok.extern.slf4j.Slf4j;
7+
import org.springframework.cache.annotation.CacheEvict;
78
import org.springframework.scheduling.annotation.Async;
89
import org.springframework.scheduling.annotation.Scheduled;
910
import org.springframework.stereotype.Component;
@@ -37,7 +38,7 @@ public class NewsSaveScheduler {
3738
Map.entry(Category.ETC, List.of("몸캠"))
3839
);
3940

40-
@Async
41+
@CacheEvict(value = "news:list:v2", allEntries = true)
4142
public void crawlingForAdmin() {
4243
crawlByCategories(EnumSet.of(
4344
Category.VOICE_PHISHING,
@@ -46,7 +47,7 @@ public void crawlingForAdmin() {
4647
));
4748
}
4849

49-
@Async
50+
@CacheEvict(value = "news:list:v2", allEntries = true)
5051
// @Scheduled(cron = "0 0 4 * * *")
5152
public void saveNewsArticles() {
5253
crawlAll();
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.blockguard.server.global.config;
2+
3+
import org.springframework.beans.factory.annotation.Value;
4+
import org.springframework.cache.CacheManager;
5+
import org.springframework.cache.annotation.EnableCaching;
6+
import org.springframework.context.annotation.Bean;
7+
import org.springframework.context.annotation.Configuration;
8+
import org.springframework.data.redis.cache.RedisCacheConfiguration;
9+
import org.springframework.data.redis.cache.RedisCacheManager;
10+
import org.springframework.data.redis.connection.RedisConnectionFactory;
11+
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
12+
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
13+
import org.springframework.data.redis.serializer.RedisSerializationContext;
14+
import org.springframework.data.redis.serializer.StringRedisSerializer;
15+
16+
import java.time.Duration;
17+
import java.util.HashMap;
18+
import java.util.Map;
19+
20+
@EnableCaching
21+
@Configuration
22+
public class RedisConfig {
23+
@Value("${spring.data.redis.host}")
24+
private String host;
25+
26+
@Value("${spring.data.redis.port}")
27+
private int port;
28+
29+
@Bean
30+
public RedisConnectionFactory redisConnectionFactory() {
31+
return new LettuceConnectionFactory(host, port);
32+
}
33+
34+
@Bean
35+
public CacheManager cacheManager(RedisConnectionFactory cf) {
36+
RedisCacheConfiguration defaultConfig = RedisCacheConfiguration.defaultCacheConfig()
37+
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
38+
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))
39+
.entryTtl(Duration.ofMinutes(30));
40+
41+
Map<String, RedisCacheConfiguration> cacheConfigs = new HashMap<>();
42+
cacheConfigs.put("news:list:v2", defaultConfig.entryTtl(Duration.ofHours(24))); // 뉴스는 하루 TTL
43+
44+
45+
return RedisCacheManager.
46+
RedisCacheManagerBuilder.
47+
fromConnectionFactory(cf)
48+
.cacheDefaults(defaultConfig)
49+
.withInitialCacheConfigurations(cacheConfigs)
50+
.build();
51+
52+
}
53+
}

0 commit comments

Comments
 (0)