์บก์คํค๋์์ธ ํ๋ก์ ํธ๋ฅผ ์งํํ๋ฉฐ ์๋ ๊ฐ์ ์ ์ํด In-Memory ๋ฐ์ดํฐ๋ฒ ์ด์ค์ธ Redis๋ฅผ ํ์ฉํ์๋ค. ํด๋น ์๋น์ค์ ๊ฒฝ์ฐ ์ฌ์ฉ์๋ก๋ถํฐ ๋จ์ด๊ฐ ์ ๋ ฅ๋๋ฉด Word2Vec ๋ชจ๋ธ์ ์ฌ์ฉํ๋ AI ์๋ฒ์ ๊ทธ์ ๋ํ ์ ์์ด๋ฅผ ์์ฒญํ๋ค. ์ด ๋ ๋งค๋ฒ ๋จ์ด๋ฅผ ๋ถ์ํ๋๋ฐ ์์๋๋ ์๊ฐ์ ์ค์ด๊ณ ์ ํน์ ๋จ์ด์ ๋ํ ๋ฆฌ์คํฐ์ค๋ฅผ ์บ์ฑํ์๋ค. ๋, ๊ฐ์ฅ ์์ฃผ ์กฐํ๋๋ ์ ๋ณด์ธ ์ ์ ์ ๋ณด๋ ์บ์ฑํ์๋ค.
์ฅ์
๋จ์
Annotation | ๊ธฐ๋ฅ |
---|---|
@Cacheable | ์บ์ ์กฐํ ํ ๋ฐํ, ์์ ๊ฒฝ์ฐ ์์ฑ |
@CachePut | ๋ฌด์กฐ๊ฑด ์บ์ ์ ์ฅ |
@CacheEvict | ์บ์ ์ญ์ |
private final Long DEFAULT_HOURS = 1L;
// ๋์์ด ์กฐํ
public final static String SYNONYM_KEY = "Synonym";
private final Long SYNONYM_HOURS = 24L;
// ์ ์ ์ ๋ณด ์กฐํ
public final static String USER_KEY = "User";
private final Long USER_HOURS = 6L;
@Bean
public CacheManager cacheManager(RedisConnectionFactory connectionFactory) {
// default configuration
RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig()
.disableCachingNullValues()
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(
new GenericJackson2JsonRedisSerializer()))
.entryTtl(Duration.ofHours(DEFAULT_HOURS));
Map<String, RedisCacheConfiguration> cacheConfigurations = new HashMap<>();
// ๋์์ด configuration
cacheConfigurations.put(SYNONYM_KEY,
RedisCacheConfiguration.defaultCacheConfig()
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(
new GenericJackson2JsonRedisSerializer())).entryTtl(Duration.ofHours(SYNONYM_HOURS)));
// ์ ์ ์ ๋ณด configuration
cacheConfigurations.put(USER_KEY,
RedisCacheConfiguration.defaultCacheConfig()
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(
new GenericJackson2JsonRedisSerializer())).entryTtl(Duration.ofHours(USER_HOURS)));
// default + custom configuration์ผ๋ก RedisCacheManager ์์ฑ ๋ฐ ๋ฐํ
return RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(connectionFactory)
.cacheDefaults(configuration)
.withInitialCacheConfigurations(cacheConfigurations).build();
}
@Getter
@Builder
@ToString
public static class EditAccountRequest {
private final String name;
private final String plan;
}
public void editAccount(UserCommand.EditAccountRequest request) {
updateName(request.getName());
updatePlan(request.getPlan());
}
public void updateName(String name) {
if (name != null) {
this.name = name;
}
}
public void updatePlan(String plan) {
if (plan != null) {
this.plan = PlanStatus.valueOf(plan);
}
}
@Operation(summary = "์ ์ ์ ๋ณด")
@Cacheable(value = USER_KEY, key = "#user.getId()", cacheManager = "cacheManager")
@GetMapping(value = "", produces = "application/json; charset=utf-8")
@ResponseBody
public CommonResponse getUserAccount(@AuthenticationPrincipal User user) {
...
}
@Operation(summary = "์ ์ ์ ๋ณด ์์ ")
@CachePut(value = USER_KEY, key = "#user.getId()", cacheManager = "cacheManager")
@PatchMapping(value = "", produces = "application/json; charset=utf-8")
@ResponseBody
public CommonResponse editUserAccount(@AuthenticationPrincipal User user,
@Valid @RequestBody UserRequest.EditAccountRequest request) {
...
}
@Operation(summary = "๋จ์ด ๋ถ์")
@Cacheable(value = SYNONYM_KEY, key = "#word", cacheManager = "cacheManager", unless = "#word==''")
@GetMapping(value = "/question", produces = "application/json; charset=utf-8")
@ResponseBody
public CommonResponse recommendSynonym(@AuthenticationPrincipal User user, @RequestParam String word) {
var formResult = formRecommendFacade.recommendSynonym(word);
var response = formResponseMapper.of(formResult);
return CommonResponse.onSuccess(response);
}