Intégration de Redis avec Spring Boot

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 :

  1. Excluez la dépendance lettuce-core de spring-boot-starter-data-redis.
  2. 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.

Étiquettes: Spring Boot Redis Java Configuration redis template

Publié le 17 juillet à 00h54