Redis est une base de données clé-valeur en mémoire, open-source et écrite en C, reconnue pour ses hautes performances. Elle prend en charge divers types de données tels que les chaînes (String), ensembles (Set), hachages (Hash), listes (List) et flux (Stream). Redis est fréquemment utilisé pour la mise en cache, les systèmes de messagerie, l'analyse en temps réel, les compteurs et les classements, en faisant un composant quasi indispensable dans les applications modernes.
Spring Boot facilite grandement l'intégration de Redis grâce à son module spring-boot-starter-data-redis. Ce composant permet une configuration et une utilisation rapides de Redis au sein d'une application Spring Boot avec un minimum d'effort.
Configuraton de Redis avec Spring Boot
Dépendances Maven
Pour intégrer Redis, vous devez ajouter les dépendances suivantes à votre fichier pom.xml :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
La dépendance commons-pool2 est nécessaire pour la gestion du pool de connexions Redis.
Propriétés de Configuration
Les paramètres essentiels de connexion à Redis peuvent être définis dans votre fichier application.yaml ou application.properties :
spring:
redis:
# Adresse de connexion
host: "localhost"
# Port
port: 6379
# Index de la base de données
database: 0
# Nom d'utilisateur (si applicable)
# username:
# Mot de passe (si applicable)
# password:
# Délai d'attente de connexion (en secondes ou millisecondes)
connect-timeout: 5s
# Délai d'attente de lecture (en secondes ou millisecondes)
timeout: 5s
# Configuration spécifique au client Lettuce
lettuce:
# Configuration du pool de connexions
pool:
# Nombre minimum de connexions inactives
min-idle: 0
# Nombre maximum de connexions inactives
max-idle: 8
# Nombre maximum de connexions actives
max-active: 8
# Délai d'attente maximal pour obtenir une connexion du pool (<= 0 signifie sans délai)
max-wait: -1ms
Note : Si vous utilisez une version de Spring Boot antérieure à 2.x, l'espace de noms de configuration est spring.data.redis au lieu de spring.redis.
Utilisation du client Jedis
Par défaut, Spring Data Redis utilise le client Lettuce. Cependant, il prend également en charge Jedis. Il est recommandé d'utiliser Lettuce car il est basé sur Netty et supporte l'IO non bloquant, offrant ainsi de meilleures performances.
Pour utiliser Jedis à la place de Lettuce :
- Excluez la dépendance
lettuce-coredespring-boot-starter-data-redis. - Ajoutez la dépendance
jedis.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
Modifiez ensuite votre fichier de configuration pour remplacer les propriétés de lettuce par celles de jedis :
spring:
redis:
# Configuration spécifique au client Jedis
jedis:
# Configuration du pool de connexions
pool:
# Nombre minimum de connexions inactives
min-idle: 0
# Nombre maximum de connexions inactives
max-idle: 8
# Nombre maximum de connexions actives
max-active: 8
# Délai d'attente maximal pour obtenir une connexion du pool
max-wait: -1ms
Utilisation de StringRedisTemplate
Une fois la configuration terminée, vous pouvez injecter et utiliser StringRedisTemplate dans vos composants Spring :
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.junit.jupiter.api.Test;
import java.time.Duration;
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class RedisIntegrationTest {
private static final Logger logger = LoggerFactory.getLogger(RedisIntegrationTest.class);
// Injection de StringRedisTemplate
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Test
public void testStringOperations() {
// Définir une valeur avec une durée d'expiration
this.stringRedisTemplate.opsForValue().set("myKey", "myValue", Duration.ofMinutes(5));
// Récupérer la valeur
String retrievedValue = this.stringRedisTemplate.opsForValue().get("myKey");
logger.info("Retrieved value: {}", retrievedValue);
}
}
Pour une liste exhaustive des opérations disponibles avec StringRedisTemplate, consultez la documentation Java.
Création d'un RedisTemplate personnalisé
Si StringRedisTemplate ne répond pas à vos besoins, vous pouvez définir votre propre implémentation de RedisTemplate. Par exemple, pour créer un JsonRedisTemplate capable de sérialiser/désérialiser des objets Java au format JSON vers/depuis Redis.
package com.example.redis.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
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;
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> jsonRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
// Sérialiseur JSON pour les valeurs
Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
// Enregistrement du module pour la prise en charge des types java.time
objectMapper.registerModule(new JavaTimeModule());
serializer.setObjectMapper(objectMapper);
// Configuration des sérialiseurs pour les clés et les valeurs
template.setKeySerializer(StringRedisSerializer.UTF_8);
template.setValueSerializer(serializer);
template.setHashKeySerializer(StringRedisSerializer.UTF_8);
template.setHashValueSerializer(serializer);
template.afterPropertiesSet(); // Important pour initialiser le template
return template;
}
}
Dans cet exemple, nous héritons de RedisTemplate<String, Object> pour permettre le stockage de n'importe quel objet Java. Le constructuer prend en paramètre RedisConnectionFactory, qui est essentielle. Nous utilisons Jackson2JsonRedisSerializer pour la sérialisation/désérialisation JSON, en incluant JavaTimeModule pour gérer correctement les dates et heures Java 8.
Voici un exemple d'utilisation de ce template personnalisé dans un contrôleur REST :
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.data.redis.core.RedisTemplate;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
@RestController
public class RedisController {
@Autowired
private RedisTemplate<String, Object> jsonRedisTemplate;
@GetMapping("/storeData")
public String storeAndRetrieveData() {
// Création d'un objet Map avec des données diverses
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("applicationName", "MySpringApp");
dataMap.put("version", "1.0.0");
dataMap.put("creationTimestamp", LocalDateTime.now());
// Stockage en tant que valeur clé-valeur
jsonRedisTemplate.opsForValue().set("app:config", dataMap, java.time.Duration.ofMinutes(10));
// Récupération de la valeur
Map<String, Object> retrievedMap = (Map<String, Object>) jsonRedisTemplate.opsForValue().get("app:config");
// Stockage dans un Hash Redis
jsonRedisTemplate.opsForHash().put("app:details", "config", dataMap);
// Récupération d'un champ du Hash
Map<String, Object> retrievedHashField = (Map<String, Object>) jsonRedisTemplate.opsForHash().get("app:details", "config");
System.out.println("Retrieved from value: " + retrievedMap);
System.out.println("Retrieved from hash field: " + retrievedHashField);
return "Data stored and retrieved successfully!";
}
}
Lors de l'exécution de cette méthode, les données seront sérialisées en JSON, stockées dans Redis, puis récupérées et désérialisées en objets Java. L'inspection des logs montrera que les données sont correctement traitées.