diff --git a/build.gradle b/build.gradle index 7c3d401..572f615 100644 --- a/build.gradle +++ b/build.gradle @@ -74,6 +74,10 @@ dependencies { runtimeOnly 'org.mariadb.jdbc:mariadb-java-client' runtimeOnly 'com.h2database:h2' + // cache + implementation 'org.springframework.boot:spring-boot-starter-cache' + implementation 'com.github.ben-manes.caffeine:caffeine' + // S3 implementation platform('com.amazonaws:aws-java-sdk-bom:1.11.1000') implementation 'com.amazonaws:aws-java-sdk-s3' diff --git a/src/main/java/com/meommu/meommuapi/core/auth/service/AuthServiceImpl.java b/src/main/java/com/meommu/meommuapi/core/auth/service/AuthServiceImpl.java index d09ea8c..2add0d4 100644 --- a/src/main/java/com/meommu/meommuapi/core/auth/service/AuthServiceImpl.java +++ b/src/main/java/com/meommu/meommuapi/core/auth/service/AuthServiceImpl.java @@ -45,36 +45,23 @@ public TokenResponse signIn(SignInRequest request) { String accessToken = jwtTokenProvider.createAccessToken(kindergarten.getId()); String refreshToken = jwtTokenProvider.createRefreshToken(kindergarten.getId()); Long expiration = jwtTokenProvider.getExpiration(refreshToken); - refreshTokenRepository.save(kindergarten.getId(), refreshToken, expiration); - return TokenResponse.from(accessToken, refreshToken); } @Override @Transactional public TokenResponse reissue(AuthInfo authInfo, ReissueRequest request) { - // 1. Refresh Token 검증 jwtTokenProvider.validateRefreshToken(request.getRefreshToken()); - - // 2. 인증정보 Long id = authInfo.getId(); - - // 3. Redis RefreshToken 조회 String refreshToken = refreshTokenRepository.findByUserId(id); if (!refreshToken.equals(request.getRefreshToken())) { throw new JwtException(MALFORMED_JWT); } - - // 3. 새로운 토큰 발급 String newAccessToken = jwtTokenProvider.createAccessToken(id); String newRefreshToken = jwtTokenProvider.createRefreshToken(id); - - // 4. Redis RefreshToken 업데이트 Long expiration = jwtTokenProvider.getExpiration(refreshToken); refreshTokenRepository.save(id, newRefreshToken, expiration); - - // 5. 토큰 반환 return TokenResponse.from(newAccessToken, newRefreshToken); } diff --git a/src/main/java/com/meommu/meommuapi/core/guide/service/GuideServiceImpl.java b/src/main/java/com/meommu/meommuapi/core/guide/service/GuideServiceImpl.java index d07b0e5..8eed337 100644 --- a/src/main/java/com/meommu/meommuapi/core/guide/service/GuideServiceImpl.java +++ b/src/main/java/com/meommu/meommuapi/core/guide/service/GuideServiceImpl.java @@ -2,6 +2,8 @@ import java.util.List; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -33,11 +35,13 @@ public GuideServiceImpl( } @Override + @Cacheable(cacheNames = "gpt_guide") public GuideResponses findGuides() { return GuideResponses.from(guideRepository.findAll()); } @Override + @Cacheable(cacheNames = "gpt_guide_detail") public GuideDetailResponses findGuideDetails(Long guideId) { List guideDetails = guideDetailRepository.findAllByGuideId(guideId); return GuideDetailResponses.from(guideDetails); @@ -45,6 +49,7 @@ public GuideDetailResponses findGuideDetails(Long guideId) { @Override @Transactional + @CacheEvict(cacheNames = "gpt_guide_detail") public GuideDetailSaveResponse createGuideDetail( Long guideId, GuideDetailSaveRequest guideDetailSaveRequest @@ -57,6 +62,7 @@ public GuideDetailSaveResponse createGuideDetail( @Override @Transactional + @CacheEvict(cacheNames = "gpt_guide_detail") public void deleteGuideDetail(Long guideId, Long detailId) { Guide guide = getGuideById(guideId); GuideDetail guideDetail = getGuideDetailById(detailId); diff --git a/src/main/java/com/meommu/meommuapi/core/notice/service/NoticeServiceImpl.java b/src/main/java/com/meommu/meommuapi/core/notice/service/NoticeServiceImpl.java index 168020a..6d518ca 100644 --- a/src/main/java/com/meommu/meommuapi/core/notice/service/NoticeServiceImpl.java +++ b/src/main/java/com/meommu/meommuapi/core/notice/service/NoticeServiceImpl.java @@ -2,6 +2,7 @@ import java.util.List; +import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -20,7 +21,9 @@ public NoticeServiceImpl(NoticeRepository noticeRepository) { } @Override + // @Cacheable(cacheNames = "notice") public NoticeResponses findNotices() { + System.out.println("캐시 이용 전"); List notices = noticeRepository.findAllByOrderByCreatedAtDesc(); return NoticeResponses.from(notices); } diff --git a/src/main/java/com/meommu/meommuapi/global/cache/CacheConfig.java b/src/main/java/com/meommu/meommuapi/global/cache/CacheConfig.java new file mode 100644 index 0000000..466f5a2 --- /dev/null +++ b/src/main/java/com/meommu/meommuapi/global/cache/CacheConfig.java @@ -0,0 +1,37 @@ +package com.meommu.meommuapi.global.cache; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import org.springframework.cache.CacheManager; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.cache.caffeine.CaffeineCache; +import org.springframework.cache.support.SimpleCacheManager; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.github.benmanes.caffeine.cache.Caffeine; + +@Configuration +@EnableCaching +public class CacheConfig { + + @Bean + public List caffeineCaches() { + return Arrays.stream(CacheType.values()) + .map(cache -> new CaffeineCache(cache.getCacheName(), + Caffeine.newBuilder().recordStats() + .expireAfterWrite(cache.getExpiredAfterWrite(), TimeUnit.SECONDS) + .maximumSize(cache.getMaximumSize()) + .build())) + .toList(); + } + + @Bean + public CacheManager cacheManager(List caffeineCaches) { + SimpleCacheManager cacheManager = new SimpleCacheManager(); + cacheManager.setCaches(caffeineCaches); + return cacheManager; + } +} \ No newline at end of file diff --git a/src/main/java/com/meommu/meommuapi/global/cache/CacheType.java b/src/main/java/com/meommu/meommuapi/global/cache/CacheType.java new file mode 100644 index 0000000..f6551e1 --- /dev/null +++ b/src/main/java/com/meommu/meommuapi/global/cache/CacheType.java @@ -0,0 +1,32 @@ +package com.meommu.meommuapi.global.cache; + +public enum CacheType { + + NOTICE("notice", 60 * 60, 10000), + + GPT_GUIDE("gpt_guide", 60 * 60, 10000), + + GPT_GUIDE_DETAIL("gpt_guide_detail", 60 * 60, 10000); + + private final String cacheName; + private final int expiredAfterWrite; + private final int maximumSize; + + CacheType(String cacheName, int expiredAfterWrite, int maximumSize) { + this.cacheName = cacheName; + this.expiredAfterWrite = expiredAfterWrite; + this.maximumSize = maximumSize; + } + + public String getCacheName() { + return cacheName; + } + + public int getExpiredAfterWrite() { + return expiredAfterWrite; + } + + public int getMaximumSize() { + return maximumSize; + } +} \ No newline at end of file