(spring boot) RedisRepository 사용하는 방법, @RedisHash
Spring Data Redis, RedisRepository 사용하는 방법
spring boot에서 인메모리 데이터 저장소인 redis를 사용하기 위해서는 org.springframework.data.redis.core 패키지에 있는 'RedisTemplate 클래스를 사용하는 방법'과 CrudRepository를 상속받는 'RedisRepository를 사용하는 방법'이 있는데요.
해당 포스팅에서는 두 번째 방법인 CrudRepository를 상속받은 인터페이스를 이용해서 Redis를 사용하는 방법에 대해서 살펴보겠습니다.
(예시에 사용된 spring boot 버전은 2.6.4 버전을 사용했으며 Jedis, Lettuce 오픈소스 라이브러리 중 spring boot 2.0부터 기본적으로 탑재된 Lettuce를 RedisClient로 사용하였습니다.)
1. 의존성 추가
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-data-redis'
(maven 또는 gradle 의존성 추가)
가장 먼저 Redis를 사용하기 위해 'spring-boot-starter-data-redis' 의존성을 추가해 줍니다.
2. RedisConfig Class 생성
@EnableRedisRepositories
@Configuration
public class RedisConfig {
@Value("${spring.redis.host}")
private String redisHost;
@Value("${spring.redis.port}")
private int redisPort;
@Bean
public RedisConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(redisHost, redisPort);
}
}
//application.yml file 중 redis 관련 설정 값
spring:
redis:
host: localhost
port: 6379
이어서 생성하는 'RedisConfig' 클래스에서는 @Value 어노테이션을 통해 .properties 또는 .yml 파일에 설정된 host 값과 port 값을 가져오고, 가져온 host, port 값을 통해 LettuceConnectionFactory를 생성하여 bean으로 등록하는데요.
이때 해당 config 클래스에 @EnableRedisRepository 어노테이션을 달아 RedisRepository를 활성화해 줍니다.
3. Redis에 저장할 자료구조 객체 Class 생성
@Builder
@Getter
@AllArgsConstructor
@NoArgsConstructor
@RedisHash(value = "refresh", timeToLive = 1209600)
public class RefreshToken {
@Id
private String id;
private String ip;
private Collection<? extends GrantedAuthority> authorities;
@Indexed
private String refreshToken;
}
spring data redis에서 redis repository 방식을 이용하면 Domain Object를 redis hash 자료구조로 쉽게 변환하여 저장할 수 있는데요.
@RedisHash의 value 값(redis keyspace)에 특정한 값을 넣어줌으로써 추후 해당 데이터에 대한 key가 생성될 때 prefix를 지정할 수 있으며, @Id 어노테이션을 통해 prefix:구분자 형태(keyspace:@id)로 데이터에 대한 키를 저장하여 각 데이터를 구분할 수 있습니다.
이때, @Id 어노테이션은 org.springframework.data.annotation.Id를 사용하며, null로 저장될 경우 랜덤 값으로 설정됩니다.
추가적인 기능으로는 @Indexed 어노테이션을 통해 secondary indexes를 적용할 수 있으며, @TimeToLive 어노테이션을 통해 TTL을 적용할 수 있습니다.
(timeToLive에 적용되는 시간은 '초' 단위이며, default 값은 -1L으로 이 경우 유효시간이 설정되지 않습니다.)
4. RedisRepository
public interface RefreshTokenRedisRepository extends CrudRepository<RefreshToken, Long> {
RefreshToken findByRefreshToken(String refreshToken);
}
(redisRepository)
CurdRepository를 상속하는 CustomInterface를 생성합니다.
redisRepository 방식은 CrudRepository를 상속받은 인터페이스가 사용되기 때문에 Spring Data JPA에서 JpaRepository를 사용하는 방식과 유사하다는 특징이 있습니다.
refreshTokenRedisRepository.save(RefreshToken.builder()
.id(authentication.getName())
.ip(Helper.getClientIp(request))
.authorities(authentication.getAuthorities())
.refreshToken(tokenInfo.getRefreshToken())
.build());
(save example)
5. Redis Data
해당 데이터는 위에서 생성한 '@Id 어노테이션과 @Indexed 어노테이션을 적용한' RefreshToken 객체가 redis에 저장되었을 때입니다.
그리고 해당 데이터는 '@Indexed 어노테이션을 사용하지 않고, @Id 어노테이션만 적용'하여 해당 객체를 저장한 경우인데요.
두 결과의 차이점을 통해 객체 필드에 @Indexed 어노테이션을 통해 index를 지정하였을 때, 위 결과와 같이 'keyspace:@Id:idx'라는 키를 가진 데이터와 'keyspace:인덱스를 적용한 필드:해당 필드의 값'이라는 키를 가진 데이터가 추가로 저장되는 것을 확인할 수 있습니다.
type 명령어를 통해 저장된 데이터의 타입을 확인해 보면 set 또는 hash 타입의 데이터가 저장된 것을 확인할 수 있습니다.
< Redis 관련 포스팅 >
2021.08.12 - [Programming/Web] - Redis란? 레디스의 기본적인 개념 (인메모리 데이터 구조 저장소)
< 참고 자료 >
https://docs.spring.io/spring-data/redis/docs/2.3.3.RELEASE/reference/html/#redis.repositories