docker run --name redis -p 8379:6379 -d redis redis-server --requirepass yourpassword
docker exec -it 컨테이너명 /bin/bash
# redis shell 접근 후
redis-cli -p 6379 -a [password]
spring:
redis:
host: localhost
port: 8379
password: [password]
현재 Deprecated되어 이를 아래와 같이 수정해줍니다.(Spring Boot 3.X 버전)
data: redis: host: localhost port: 8379 password: [password]
4-2. Java Configuration
@Configuration @EnableRedisRepositories public class RedisConfiguration { private Logger log = LoggerFactory.getLogger(RedisConfiguration.class); @Value("${spring.data.redis.host}") private String host @Value("${spring.data.redis.port}") private int port; @Value("${spring.data.redis.password}") private String password; /** * Redis와 연결 * @return RedisConnectionFactory */ @Bean public RedisConnectionFactory redisConnectionFactory() { RedisStandaloneConfiguration redisConfiguration = new RedisStandaloneConfiguration(); redisConfiguration.setHostName(host); redisConfiguration.setPort(port); redisConfiguration.setPassword(password); return new LettuceConnectionFactory(redisConfiguration); } /** * RedisConnection에서 넘겨준 byte값 객체 직렬화 * @return RedisTemplate<?, ?> */ @Primary @Bean public RedisTemplate<String, String> redisTemplate() { RedisTemplate<String, String> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(redisConnectionFactory()); redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(new StringRedisSerializer()); return redisTemplate; } }
@Primary는 동일한 타입의 여러 빈이 존재할 경우 기본 Bean으로 정의할 것을 지정합니다.
public interface RedisService {
/**
* Redis 연결 여부 확인
* @return boolean
*/
boolean isConnected();
/**
* 특정 데이터를 저장
* @param key 키
* @param value 값
* @param duration 만료 시간
*/
void setDataExpire(String key, String value, long duration);
/**
* 특정 키 값 삭제
* @param key 키
*/
void deleteData(String key);
/**
* 특정 키의 값을 가져옴
* @param key 키
* @return 값
*/
String getData(String key);
/**
* 특정 키에 해당하는 값의 존재 유무
* @param key 키
* @return 값의 존재 유무
*/
boolean existData(String key);
}
@RequiredArgsConstructor
@Service
public class RedisServiceImpl implements RedisService {
private final RedisTemplate<String, String> redisTemplate;
private final Logger log = LoggerFactory.getLogger(RedisService.class);
@Override
public boolean isConnected() {
try {
String pingResponse = redisTemplate.getConnectionFactory().getConnection().ping();
return "PONG".equals(pingResponse);
} catch (Exception e) {
return false;
}
}
@Override
public void setDataExpire(String key, String value, long duration) {
ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
Duration expireDuration = Duration.ofSeconds(duration);
valueOperations.set(key, value, expireDuration);
}
@Override
public void deleteData(String key) {
redisTemplate.delete(key);
}
@Override
public String getData(String key) {
ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
return valueOperations.get(key);
}
@Override
public boolean existData(String key) {
return Boolean.TRUE.equals(redisTemplate.hasKey(key));
}
}
테스트 코드를 습관을 들이는 중이기 때문에 다소 부족할 수 있습니다.
@SpringBootTest
class RedisServiceImplTest {
@Autowired
RedisService redisService;
Logger log = LoggerFactory.getLogger(RedisServiceImplTest.class);
@Test
@DisplayName("연결 확인 - isConnected")
void isConnected() {
boolean connected = redisService.isConnected();
// 연결 확인
assertTrue(connected, "Redis와 연결하지 못했습니다.");
}
@Test
@DisplayName("만료기간 있는 데이터를 저장 - setDataExpire")
void setDataExpire() throws InterruptedException {
redisService.setDataExpire("TEST", "1234", 10);
String redisData = redisService.getData("TEST");
// 데이터 검증
assertNotNull(redisData, "Redis에서 데이터를 검색하지 못했습니다.");
assertEquals("1234", redisData, "검색된 데이터가 예상과 다릅니다.");
// 만료 시간 후 데이터 검증
Thread.sleep(10000); // 10초 대기
redisData = redisService.getData("TEST");
assertNull(redisData, "데이터가 만료 시간 후에도 여전히 존재합니다.");
}
@Test
@DisplayName("특정 데이터를 삭제 - deleteData")
void deleteData() {
redisService.setDataExpire("TEST", "1234", 10);
redisService.deleteData("TEST");
// 데이터 검증
String redisData = redisService.getData("TEST");
assertNull(redisData, "Redis에서 데이터를 삭제하지 못했습니다.");
}
@Test
@DisplayName("특정 데이터 조회 - getData")
void getData() {
redisService.setDataExpire("TEST", "1234", 10);
String redisData = redisService.getData("TEST");
assertNotNull(redisData, "Redis에서 데이터를 검색하지 못했습니다.");
}
@Test
@DisplayName("특정 데이터가 존재하는지 여부 - existData")
void existData() {
redisService.setDataExpire("TEST", "1234", 10);
boolean existData = redisService.existData("TEST");
assertTrue(existData, "Redis에서 데이터를 검색하지 못했습니다.");
}
}