SpringBootのキャッシングをRedisで使ってみる
例えば、DBから取得した結果を返却するというメソッドがあるとする。 このメソッドに@Cacheableを付与すると、検索結果をキャッシュに格納してくれて次回呼び出し時はキャッシュで保持しているデータを返却してくれる。 基本的にキャッシュにデータがある限りDBへのアクセスは行わず、キャッシュが消されると再びDBにアクセスして再度キャッシュする。 マスタデータの保持なんかで便利そう。
準備
build.gradle
・下記を追加
implementation 'org.springframework.boot:spring-boot-starter-cache:2.5.4' implementation 'org.springframework.boot:spring-boot-starter-data-redis:2.5.4'
application.yml
・キャッシュプロバイダーはRedisを使用する
cache: type: redis redis: host: localhost port: 16379 database: 0 password: timeout: 3000
SampleApplication.java
・@EnableCachingでキャッシュを有効化
@SpringBootApplication @EnableScheduling @EnableCaching public class SampleApplication {
UserCacheObject.java
・キャッシュ用オブジェクト
package sample.service.cache; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Component; import sample.service.common.utils.JsonUtils; import sample.service.domain.repository.UserRepository; import sample.service.domain.repository.model.User; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor @Component public class UserCacheObject { private final UserRepository userRepository; @Cacheable(cacheNames = "sample-cache", key = "#key") public String findByUserId(Long userId, String key) { User user = userRepository.findById(userId); return JsonUtils.convertToJson(user); } }
UserCacheBL.java
・ビジネスロジックインタフェース
package sample.service.domainbl; import sample.service.domain.repository.model.User; public interface UserCacheBL { User findById(Long userId); }
UserCacheBLImpl.java
・ビジネスロジック実装クラス
package sample.service.domainbl.impl; import org.springframework.stereotype.Component; import sample.service.cache.UserCacheObject; import sample.service.common.utils.JsonUtils; import sample.service.domain.repository.model.User; import sample.service.domainbl.UserCacheBL; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor @Component public class UserCacheBLImpl implements UserCacheBL { private final UserCacheObject userCacheObject; @Override public User findById(Long userId) { String json = userCacheObject.findByUserId(userId, "User::" + userId); return JsonUtils.convertFromJson(json, User.class); } }
ScheduledTasks.java
・スケジュールタスクでビジネスロジックを呼び出す
package sample.service.common.tasks; import java.util.Date; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import sample.service.common.utils.DateUtils; import sample.service.domain.repository.model.User; import sample.service.domainbl.UserCacheBL; import lombok.RequiredArgsConstructor; @Component @RequiredArgsConstructor public class ScheduledTasks { private static final Logger LOGGER = LoggerFactory.getLogger(ScheduledTasks.class); private final UserCacheBL userCacheBL; @Scheduled(initialDelay = 10000, fixedRate = 1000) public void doSomething() { User user = userCacheBL.findById(5L); LOGGER.info("### User : {}", user); LOGGER.info("### This time is : {}", DateUtils.format(new Date())); } }
結果
こんな感じでRedisに格納された。
127.0.0.1:6379> keys * 1) "sample-cache::User::1" 127.0.0.1:6379> get sample-cache::User::1 "\xac\xed\x00\x05t\x00\xcf{\"id\":1,\"userName\":\"Jack\",\"mailAddress\":\"jack@hoge.example.jp\",\"password\":\"8bb0cf6eb9b17d0f7d22b456f121257dc1254e1f01665370476383ea776df414\",\"registTime\":1629500509000,\"updateTime\":1629500509000,\"deleted\":0}" 127.0.0.1:6379> del sample-cache::User::1 (integer) 1 127.0.0.1:6379> keys * 1) "sample-cache::User::1"