Skip to content

3. Spring Boot Integration

To get started, you need to tell Maven or Gradle which libraries your project needs. For Redis, there are two primary dependencies you’ll encounter.

  • What it is: This is the core starter dependency for any Redis integration.
  • What it does: It pulls in all the necessary libraries for connecting to and interacting with Redis. This includes:
    1. Spring Data Redis: The core project that provides the RedisTemplate and repository abstractions.
    2. Lettuce (or Jedis): The actual low-level Java client library that handles the network communication with the Redis server. Spring Boot defaults to Lettuce, which is a modern, non-blocking, and high-performance client.
  • When to use it: You always need this dependency when your application needs to directly talk to Redis (e.g., for caching, distributed locks, pub/sub, etc.).

Maven Example:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
  • What it is: This is a specialized starter for using Redis as a session store.
  • What it does: It builds on top of spring-boot-starter-data-redis. It automatically configures Spring Session to transparently replace the default in-memory web server session management (e.g., Tomcat’s) with a Redis-backed implementation.
  • When to use it: Use this specifically when you want to achieve centralized session management for a horizontally scalable, stateless web application.

Maven Example:

<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>

Note: Adding this starter is often all you need to do to enable Redis session management, aside from the connection configuration.


3.2 Configuring Redis Connection (application.properties)

Section titled “3.2 Configuring Redis Connection (application.properties)”

Once the dependencies are in your project, you need to tell Spring Boot how to connect to your Redis server. This is typically done in your application.properties or application.yml file.

Spring Boot’s auto-configuration will pick up these properties and create a configured connection factory for you.

Common Properties:

  • spring.data.redis.host: The hostname or IP address of your Redis server. (Default: localhost)
  • spring.data.redis.port: The port your Redis server is listening on. (Default: 6379)
  • spring.data.redis.password: The password for your Redis server, if you have one set up. (Default: none)
  • spring.data.redis.database: The Redis database index to connect to. (Default: 0)
  • spring.data.redis.ssl.enabled: Set to true if your Redis server requires an SSL/TLS connection.

Example application.properties:

# The server where Redis is running
spring.data.redis.host=127.0.0.1
# The port for the Redis server
spring.data.redis.port=6379
# If your Redis is password protected
# spring.data.redis.password=your-super-secret-password
# For connecting to a cloud provider like Redis Labs or ElastiCache over SSL
# spring.data.redis.ssl.enabled=true

With just the dependency and these properties, Spring Boot will auto-configure a RedisTemplate bean that you can inject and use immediately.


Spring Data Redis provides two main template helpers for interacting with Redis. Choosing the right one is important for readability and debugging.

  • What it is: This is the general-purpose, highly flexible template. It’s designed to work with any Java Object for its keys and values.
  • How it works (by default): It uses JDK Serialization to convert your Java objects into a binary format (byte[]) before sending them to Redis.
  • The BIG Problem: The resulting keys and values in Redis are binary gibberish. They are completely unreadable by humans and other non-Java applications.

Example Scenario:

  • Java Code:
    // Assuming 'redisTemplate' is RedisTemplate<Object, Object>
    User user = new User("id-123", "Alice");
    redisTemplate.opsForValue().set("user:123", user);
    ```* **What you see in Redis CLI (`redis-cli`):**

    GET “user:123” “\xac\xed\x00\x05sr\x00\x1ccom.example.User\x84…\xb3…” // Unreadable binary data

  • What it is: This is a specialized subclass of RedisTemplate<String, String>. It is strictly for cases where both your keys and values are plain Strings.
  • How it works: It is pre-configured to use a StringRedisSerializer for both keys and values. This means it stores everything as human-readable UTF-8 strings.
  • The Advantage: It’s perfect for simple use cases and makes debugging in the Redis CLI incredibly easy. You can see exactly what’s being stored.

Example Scenario:

  • Java Code:
    // Assuming 'stringRedisTemplate' is a StringRedisTemplate
    stringRedisTemplate.opsForValue().set("user:name:123", "Alice");
  • What you see in Redis CLI (redis-cli):
    > GET "user:name:123"
    "Alice" // Perfectly readable!

Summary:

  • Use StringRedisTemplate when you are absolutely sure both key and value are Strings.
  • Use RedisTemplate for storing complex objects, BUT you must re-configure its default serializer (see next section).

3.4 Serializers (Why JSON is better than default JDK)

Section titled “3.4 Serializers (Why JSON is better than default JDK)”

A Serializer is the component that defines how a Java object is converted to and from the byte[] format that Redis understands. This is the single most important configuration choice you will make.

The Default: JdkSerializationRedisSerializer

Section titled “The Default: JdkSerializationRedisSerializer”

As mentioned, RedisTemplate uses this by default.

Why you should almost NEVER use it in production:

  1. Not Human-Readable: Debugging is a nightmare. You cannot use the redis-cli to inspect or fix data because it’s in a binary format.
    • JDK: \xac\xed\x00\x05...
    • JSON: {"id":"123", "name":"Alice"} (You can immediately see the problem if a value is wrong).
  2. Language-Specific (Poor Interoperability): The binary format is specific to Java. If you have a microservice written in Python, Node.js, or Go, it will have no way to read the data your Spring Boot app writes. This locks you into a single language and cripples a multi-language architecture.
  3. Brittle and Fragile: It is tightly coupled to the exact class definition (.class). If you save an object of User version 1, and then deploy a new version of your app where you’ve added or removed a field from the User class, trying to read the old data will often throw a java.io.InvalidClassException. This can bring your application down.

The Solution: JSON Serializers (Jackson2JsonRedisSerializer or GenericJackson2JsonRedisSerializer)

Section titled “The Solution: JSON Serializers (Jackson2JsonRedisSerializer or GenericJackson2JsonRedisSerializer)”

This approach uses the standard Jackson library to convert your Java objects into JSON strings before storing them.

Why JSON is the industry-standard choice:

  1. Human-Readable: JSON is a text format. You can easily GET a key in the redis-cli and see the exact data being stored, making debugging and manual inspection trivial.
  2. Language-Agnostic (Excellent Interoperability): JSON is a universal data interchange format. Your Spring Boot app can write a User object, and a Python script can read and parse it without any issues. This is essential for modern microservices.
  3. Flexible and Resilient: JSON is flexible with schemas. If you add a new field to your User class in Java, older JSON objects in Redis that are missing this field can still be deserialized correctly (the new field will just be null). This makes application updates much safer.

How to Configure a JSON Serializer in Spring Boot

Section titled “How to Configure a JSON Serializer in Spring Boot”

You cannot set this in application.properties. You must define a RedisTemplate bean in one of your @Configuration classes. This configuration will override the default RedisTemplate provided by Spring Boot.

This is the standard, production-ready configuration:

import com.fasterxml.jackson.databind.ObjectMapper;
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> redisTemplate(RedisConnectionFactory connectionFactory) {
// Create a new RedisTemplate
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
// Use StringRedisSerializer for keys
// Ensures keys are stored as human-readable strings
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
// Use Jackson2JsonRedisSerializer for values
// This will serialize/deserialize Java objects to/from JSON
Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
// You might need to configure the ObjectMapper for things like date formats or polymorphism
// ObjectMapper objectMapper = new ObjectMapper()...;
// serializer.setObjectMapper(objectMapper);
template.setValueSerializer(serializer);
template.setHashValueSerializer(serializer);
template.afterPropertiesSet();
return template;
}
}

By defining this bean, whenever you @Autowired a RedisTemplate<String, Object> into your services, you will get this properly configured instance, ready to store objects as clean, readable, and interoperable JSON.