Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 31

Integrating Spring Boot with Redis using Spring Data Redis

Recommended resources

Hello! Let's get started with the second lesson in our module on distributed state management.

In the last lesson, we explored why Redis is a great fit for our rate limiter and learned about the fundamental STRING and HASH data structures. You now have the theoretical knowledge of which data structures to use for algorithms like the Fixed Window and Token Bucket.

The next logical step is to bridge the gap between our Spring Boot application and the Redis server. This lesson is all about the "how"—how to establish that connection so we can start manipulating those data structures from our Java code.

Your learning outcome for this lesson:

You will connect a Spring Boot application to Redis using Spring Data Redis. This involves adding the right dependencies, configuring the connection details, and understanding the key Spring components that make it all work.



1. Setting Up Your Redis Instance

Before our application can connect to Redis, we need a Redis server running. The most straightforward way to get a local instance up and running for development is by using Docker. Since you have experience with various developer tools, this should be a quick process.

Spring Data Redis's Property-Based Configuration

The Baeldung article on Spring Data Redis provides a simple Docker command to start a Redis instance. We'll use this to get our environment ready.

Read the short section titled 'Running Redis'. It provides a single Docker command to pull the Redis image and run a container. You can execute this command in your terminal. For our purposes, you can omit the --requirepass "mypass" part to run a password-less instance locally, which simplifies our initial configuration.

After running the command, you should have a Redis server listening on its default port, 6379.


2. Adding the Spring Data Redis Dependency

To enable Redis support in our Spring Boot project, we need to add the spring-boot-starter-data-redis dependency. This starter brings in all the necessary libraries, including the core Spring Data Redis framework and a Redis client library.

How to Integrate Redis with Spring Boot

Let's add the required dependency to your project's pom.xml.

Refer to the 'Prerequisites' section of this article. Copy the Maven dependency for spring-boot-starter-data-redis into the <dependencies> section of your pom.xml file. You can ignore the commons-pool2 and reactive dependencies for now; the base starter is sufficient.

Once you've added the dependency and refreshed your Maven project, Spring Boot will be capable of auto-configuring the connection to Redis.


3. Configuring the Connection in application.yml

Spring Boot's auto-configuration works by detecting the spring-boot-starter-data-redis dependency on the classpath and then looking for connection properties in your application.yml (or .properties) file.

How to Integrate Redis with Spring Boot

Now, let's tell our application where to find the Redis server we started in step 1.

Look at the 'Application Properties' section. Copy the spring.redis configuration into your application.yml file. Since your Redis instance is running locally without a password, your configuration will be very simple.

Here is what the configuration should look like in your src/main/resources/application.yml:

spring:
  data:
    redis:
      host: localhost
      port: 6379

A quick note on property naming: modern Spring Boot versions (3.x and later) use the spring.data.redis.* prefix. Older versions used spring.redis.*. It's good practice to use the current spring.data.redis prefix.

With just the dependency and these two lines of configuration, your Spring Boot application will automatically establish a connection to Redis on startup.


4. How It Works: RedisConnectionFactory and RedisTemplate

This "magic" of auto-configuration is worth understanding, as it's a core principle of Spring Boot. Here’s what happens behind the scenes:

  1. RedisConnectionFactory: Based on your properties, Spring Boot creates a bean of type RedisConnectionFactory. This factory is responsible for creating and managing the low-level connections to the Redis server. By default, Spring Boot uses Lettuce as the client library, so it will create a LettuceConnectionFactory.
  2. RedisTemplate: Spring Boot then creates a RedisTemplate<Object, Object> bean and injects the RedisConnectionFactory into it. The RedisTemplate is a high-level abstraction that provides a rich, convenient API for you to interact with Redis. It handles things like serialization and connection management, so you can focus on the operations you want to perform (e.g., SET, INCR).

This layered architecture decouples your application code from the specific Redis client library being used.

Spring Boot Redis Connection Architecture
This diagram shows how your application interacts with the high-level `RedisTemplate`. The template uses a `RedisConnectionFactory` (which could be backed by Lettuce or another client) to communicate with the Redis server. This abstraction is a key part of the Spring Data framework.

The RedisTemplate is thread-safe, making it suitable for use in the multi-threaded environment of a web server. You can inject it directly into your services or components.


5. Best Practice: Explicit Serializer Configuration

While the auto-configured RedisTemplate<Object, Object> works, it uses Java's default serialization. This stores keys and values in a binary format that is not human-readable in a Redis command-line interface and can be brittle across different Java versions.

For a production-quality application, it's better to explicitly control serialization. For our rate limiter, we know that keys will always be strings. Values will often be simple numeric strings or, for more complex data, can be stored as JSON.

Let's create a configuration class to define our own RedisTemplate bean with sensible serializers.

How to Integrate Redis with Spring Boot

This article provides a clean example of a RedisConfig class where we can customize the RedisTemplate.

Read the 'Redis Configuration Class' section. We will implement a similar configuration class in our project.

Create a new Java class RedisConfig in a config package. Here is a version tailored for our needs. We'll configure it to use string serializers for both keys and values by default. This is perfect for the simple counters (INCR) we'll need for our first distributed algorithm.

package com.example.ratelimiter.config; // Use your project's package structure

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.StringRedisSerializer;

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<String, String> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);
        
        // Use StringRedisSerializer for serializing keys and values
        StringRedisSerializer stringSerializer = new StringRedisSerializer();
        template.setKeySerializer(stringSerializer);
        template.setValueSerializer(stringSerializer);
        template.setHashKeySerializer(stringSerializer);
        template.setHashValueSerializer(stringSerializer);
        
        template.afterPropertiesSet();
        return template;
    }
}

By defining this bean, you are overriding Spring Boot's default RedisTemplate<Object, Object>. Now, when you @Autowired a RedisTemplate<String, String>, Spring will inject this custom-configured instance. This ensures that when you save a key like ratelimit:ip:127.0.0.1, it's stored as a readable string in Redis.


6. Verifying the Connection

You've added the dependency, set the properties, and configured the template. How do you know it's working? You can write a simple component that pings the Redis server on application startup.

Create a new class, for example, RedisConnectionVerifier.

package com.example.ratelimiter.config; // Use your project's package structure

import org.springframework.boot.CommandLineRunner;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

@Component
public class RedisConnectionVerifier implements CommandLineRunner {

    private final RedisTemplate<String, String> redisTemplate;

    public RedisConnectionVerifier(RedisTemplate<String, String> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Override
    public void run(String... args) throws Exception {
        try {
            String pong = redisTemplate.getConnectionFactory().getConnection().ping();
            System.out.println("Successfully connected to Redis. PING response: " + pong);
        } catch (Exception e) {
            System.err.println("Failed to connect to Redis: " + e.getMessage());
        }
    }
}

When you run your Spring Boot application now, you should see "Successfully connected to Redis" printed to the console. This confirms that all the pieces are correctly wired together.



Conclusion

Excellent work! You have successfully laid the pipeline from your Spring Boot application to a Redis server. This is a critical piece of infrastructure for building our distributed rate limiter.

Key Takeaways:

  • Connecting to Redis in Spring Boot requires the spring-boot-starter-data-redis dependency.
  • Spring Boot's auto-configuration simplifies connection by reading spring.data.redis.* properties from application.yml.
  • The core components are RedisConnectionFactory (manages connections) and RedisTemplate (provides a high-level API for operations).
  • For production systems, it is best practice to explicitly configure a RedisTemplate bean with appropriate serializers (like StringRedisSerializer) for readable and reliable data storage.
  • You can verify the connection programmatically by pinging the Redis server.

Next Steps

Now that the communication channel is open, it's time to start using it. In the next lesson, you will perform basic Redis operations: GET, SET, INCR, and EXPIRE. You'll finally be able to implement the fixed window counter algorithm using the INCR command you learned about in the previous lesson, but this time on a distributed state store.