Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ dependencies {
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.springframework.security:spring-security-test")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")

// Redis
implementation("org.springframework.boot:spring-boot-starter-data-redis")
implementation("com.github.codemonstur:embedded-redis:1.4.3")
}

tasks.withType<Test> {
Expand Down
56 changes: 56 additions & 0 deletions src/main/java/com/back/global/config/EmbeddedRedisConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.back.global.config;

import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import redis.embedded.RedisServer;

import java.io.IOException;
import java.net.ServerSocket;

/**
* Embedded Redis 설정 클래스
* - 개발 및 테스트 환경에서만 활성화 (dev, test 프로파일)
* - 애플리케이션 시작 시 내장 Redis 서버 시작
* - 애플리케이션 종료 시 내장 Redis 서버 중지
*/
@Configuration
@Profile({"dev", "test"})
public class EmbeddedRedisConfig {

private RedisServer redisServer;
private int port;

@PostConstruct
public void startRedis() {
try {
this.port = findAvailablePort();
this.redisServer = new RedisServer(port);
this.redisServer.start();
System.setProperty("spring.data.redis.port", String.valueOf(port));
} catch (IOException e) {
throw new IllegalStateException("Failed to start embedded Redis", e);
}
}

@PreDestroy
public void stopRedis() {
try {
if (redisServer != null && redisServer.isActive()) {
redisServer.stop();
}
} catch (IOException e) {
throw new IllegalStateException("Failed to stop embedded Redis", e);
}
}

private int findAvailablePort() {
try (ServerSocket socket = new ServerSocket(0)) {
socket.setReuseAddress(true);
return socket.getLocalPort();
} catch (IOException e) {
throw new IllegalStateException("No available port found", e);
}
}
}
36 changes: 36 additions & 0 deletions src/main/java/com/back/global/config/RedisConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.back.global.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
* Redis 설정 클래스
*/
@Configuration
public class RedisConfig {

/**
* RedisTemplate 설정
* - Key: String
* - Value: JSON (Jackson)
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);

// Key: String
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());

// Value: JSON
template.setValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class));
template.setHashValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class));

return template;
}
}
5 changes: 5 additions & 0 deletions src/main/resources/application-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ spring:
username: sa
password:

data:
redis:
host: localhost
port: 6379

config:
import: optional:file:.env[.properties]

Expand Down
31 changes: 31 additions & 0 deletions src/test/java/com/back/RedisConnectionTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.back;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.test.context.ActiveProfiles;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest
@ActiveProfiles("test")
class RedisConnectionTest {

@Autowired
private StringRedisTemplate redisTemplate;

@Test
void redisShouldStoreAndGetValue() {
// given
String key = "test:key";
String value = "hello";

// when
redisTemplate.opsForValue().set(key, value);
String result = redisTemplate.opsForValue().get(key);

// then
assertThat(result).isEqualTo(value);
}
}
Loading