Spring에서 Redis 사용
레디스 관련 설명은 여기를 참고해 주세요!
🏷️ Redis 의존성
// redis
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
🏷️ Redis 설정
@RequiredArgsConstructor
@EnableRedisRepositories
@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 redisPassword;
@Bean
public RedisConnectionFactory redisConnectionFactory() {
// Redis 명령이 2초 안에 완료되지 않으면 타임아웃을 발생시키기 위한 설정
LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder()
.commandTimeout(Duration.ofSeconds(2))
.build();
// RedisStandaloneConfiguration에 호스트, 포트, 패스워드 설정
RedisStandaloneConfiguration redisConfig = new RedisStandaloneConfiguration();
redisConfig.setHostName(redisHost); // 호스트 서정
redisConfig.setPort(redisPort); // 포트 설정
redisConfig.setPassword(redisPassword); // 패스워드 설정
return new LettuceConnectionFactory(redisConfig, clientConfig);
}
@Bean
public RedisTemplate<String, UserAccount> userAccountRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
// 템플릿의 레디스의 키 벨류를 설정
RedisTemplate<String, UserAccount> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory); // 레디스 템플릿과 연결할 펙토리 셋팅
redisTemplate.setKeySerializer(new StringRedisSerializer()); // 키 직렬화시 키를 문자열로 변환해 저장
// 직렬화할 타입 명시 -> UserAccount를 JSON형식으로 변환해 저장
redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(UserAccount.class));
return redisTemplate;
}
}
🏷️ Redis에서 저장, 조회를 위해 레포지토리 작성
userId를 기준으로 관리를 할 것이기 때문에 아래와 같이 작성했습니다.
@Slf4j
@RequiredArgsConstructor
@Repository
public class UserAccountCacheRepository {
// redis에 저장, 가져오기 위한 레포지토리
private final RedisTemplate<String, UserAccount> userAccountRedisTemplate;
// redis에 저장되어 있는 일수 지정
private final static Duration USER_CACHE_TTL = Duration.ofDays(3);
public void setUserAccount(UserAccount userAccount) {
String key = getKey(userAccount.getUserId());
log.info("Redis에 UserAccount를 셋팅 {} , {}", userAccount, key);
userAccountRedisTemplate.opsForValue().set(key, userAccount, USER_CACHE_TTL);
}
public Optional<UserAccount> getUserAccount(String userId){
String key = getKey(userId);
UserAccount userAccount = userAccountRedisTemplate.opsForValue().get(key);
return Optional.ofNullable(userAccount);
}
public void deleteUserAccount(String userId) {
String key = getKey(userId);
log.info("Redis에서 UserAccount를 삭제합니다. 키: {}", key);
userAccountRedisTemplate.delete(key);
}
private String getKey(String userId) {
return "USER:" + userId;
}
}
위와 같이 userId를 가지고 UserAccount 객체를 저장하는 레포지토리를 작성했습니다.
🏷️ Redis를 사용한 조회 메소드
public UserAccount getUserAccountOrException(String userId) {
// redis에서 먼처 찾고 없는 경우 userAccount 저장소에서 찾도록 함
return userAccountCacheRepository.getUserAccount(userId).orElseGet(() ->
userAccountRepository.findById(userId).orElseThrow(
() -> new DoubleSApplicationException(
ErrorCode.USER_NOT_FOUND, String.format("%s를 찾지 못했습니다", userId))
)
);
}
아래와 같이 사용했습니다.
// 로그인
public String login(String userId, String password) {
// 회원 가입 체크
UserAccount userAccount = serviceUtils.getUserAccountOrException(userId);
// 비밀 번호 체크
if (!encoder.matches(password, userAccount.getPassword())) {
throw new DoubleSApplicationException(ErrorCode.INVALID_PASSWORD);
}
userAccountCacheRepository.setUserAccount(userAccount);
// 토큰 생성
return JwtTokenUtils.createJwtToken(userId, secretKey, expiredTimeMs);
}
'코딩 공부 > web & Java' 카테고리의 다른 글
[JPA] @PrePersist와 @PreUpdate (0) | 2024.10.18 |
---|---|
[JPA] @GeneratedValue의 GenerationType에 AUTO, IDENTITY 차이 (0) | 2024.10.17 |
[Spring / WebSocket] WebSocket와 STOMP (0) | 2024.10.05 |
[Spring / SSE] SSE(Server Sent Event) (1) | 2024.10.04 |
[Spring / Redis] Redis LocalDateTime 역직렬화 오류 (2) | 2024.10.03 |