1. 概述
Spring Data Redis 提供了一種便捷的方式來與 Redis 實例集成。
然而,在某些情況下,使用嵌入式服務器比創建具有真實服務器的環境更方便。
因此,我們將學習如何設置和使用嵌入式 Redis 服務器。
2. 依賴項
讓我們首先添加必要的依賴項:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>com.github.codemonstur</groupId>
<artifactId>embedded-redis</artifactId>
<version>1.4.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>spring-boot-starter-test 依賴包包含了我們運行集成測試所需的一切。
此外, embedded-redis 包含我們將使用的嵌入式服務器。
3. 部署
在添加依賴項後,我們應該定義 Redis 服務器與應用程序之間的連接設置。
讓我們首先創建一個用於存儲我們屬性的類:
@Configuration
public class RedisProperties {
private int redisPort;
private String redisHost;
public RedisProperties(
@Value("${spring.data.redis.port}") int redisPort,
@Value("${spring.data.redis.host}") String redisHost) {
this.redisPort = redisPort;
this.redisHost = redisHost;
}
// getters
}接下來,我們應該創建一個配置類,該類定義連接並使用我們的屬性:
@Configuration
@EnableRedisRepositories
public class RedisConfiguration {
@Bean
public LettuceConnectionFactory redisConnectionFactory(
RedisProperties redisProperties) {
return new LettuceConnectionFactory(
redisProperties.getRedisHost(),
redisProperties.getRedisPort());
}
@Bean
public RedisTemplate<?, ?> redisTemplate(LettuceConnectionFactory connectionFactory) {
RedisTemplate<byte[], byte[]> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
return template;
}
}配置非常簡單。此外,它還允許我們在不同的端口上運行嵌入式服務器。
請查看我們的 Spring Boot 與 Redis 介紹文章,以瞭解更多關於 Spring Boot 和 Redis 的信息。
4. 內嵌 Redis 服務器
現在,我們將配置內嵌服務器並將其用於一個測試用例。
首先,讓我們在測試資源目錄 (<em src/test/resources) 中創建一個 <em application.properties 文件:
spring.data.redis.host=localhost
spring.data.redis.port=6370之後,我們將創建一個帶有 @TestConfiguration 註解的類:
@TestConfiguration
public class TestRedisConfiguration {
private RedisServer redisServer;
public TestRedisConfiguration(RedisProperties redisProperties) throws IOException {
this.redisServer = new RedisServer(redisProperties.getRedisPort());
}
@PostConstruct
public void postConstruct() throws IOException {
redisServer.start();
}
@PreDestroy
public void preDestroy() throws IOException {
redisServer.stop();
}
}服務器將在上下文中建立後啓動。在我們的機器上,它將在我們定義的端口上啓動。
例如,我們現在可以無需停止實際的 Redis 服務器即可運行測試。
理想情況下,我們希望它在隨機可用的端口上啓動,但嵌入式 Redis 目前還沒有這個功能。我們現在可以嘗試通過 ServerSocket API 獲取隨機端口。
此外,當上下文中被銷燬時,服務器也會停止。
服務器還可以通過我們的可執行文件提供。
this.redisServer = new RedisServer("/path/redis", redisProperties.getRedisPort());此外,可執行文件可以針對每個操作系統進行定義:
RedisExecProvider customProvider = RedisExecProvider.defaultProvider()
.override(OS.UNIX, "/path/unix/redis")
.override(OS.Windows, Architecture.x86_64, "/path/windows/redis")
.override(OS.MAC_OS_X, Architecture.x86_64, "/path/macosx/redis")
this.redisServer = new RedisServer(customProvider, redisProperties.getRedisPort());最後,讓我們創建一個測試,它將使用我們的 TestRedisConfiguration 類:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = TestRedisConfiguration.class)
public class UserRepositoryIntegrationTest {
@Autowired
private UserRepository userRepository;
@Test
public void shouldSaveUser_toRedis() {
UUID id = UUID.randomUUID();
User user = new User(id, "name");
User saved = userRepository.save(user);
assertNotNull(saved);
}
}用户已成功保存到我們的嵌入式 Redis 服務器。
此外,我們還手動將 TestRedisConfiguration 添加到 SpringBootTest 中。 如前所述,服務器在測試之前啓動,並在測試之後停止。
5. 結論
嵌入式 Redis 服務器是完美地替代測試環境實際服務器的工具。我們已經瞭解瞭如何配置和使用它在我們的測試中。