In the previous article, we learned how to use the Redis key-value store as a NoSQL database. In this article, we will learn how to use the Redis store as a messaging broker with Spring Boot.
We will create producer and consumer applications. We will also learn how to publish the message to the Redis server and listen to the message from the consumer application.
Version details:
- Spring Boot version: 2.3.1.RELEASE
- Java version 1.8
- Redis for windows version: 3.2.100
Table of Contents
- Installing Redis
- Redis producer application
- Redis consumer application
- Testing the application
- Conclusion
Installing Redis
If we are using the Windows system, we can download the slightly outdated Redis server in the zip from here.
Now, unzip the downloaded zip file, and start the server by running the redis-server executable file.

If you are using Mac OS X/Linux, you can use brew and execute the following command in the terminal.
$ brew update && brew install redis
Redis producer application
Let us create a producer application first that produces the message to the Redis server.
Creating the Spring Boot application
Create a Spring boot application and add the below dependencies in the pom file.
We are using spring data redis, web starter dependencies, and also Lombok dependencies in our application.
Also, the spring boot data redis starter dependency provides all the required basic configurations for our Spring Boot application to interact with the Redis server.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency>
Creating a DTO class
Create a Student DTO class.
We will pass this student object to the Redis messaging broker.
package com.asbnotebook.dto; import java.time.LocalDate; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; import lombok.Getter; import lombok.Setter; import lombok.ToString; @Getter @Setter @ToString public class Student { private Integer id; private String name; @JsonSerialize(using = LocalDateSerializer.class) @JsonFormat(pattern = "dd/MM/yyyy") private LocalDate dob; }
We have used the LocalDateSerializer class to serialize the input date JSON fields. The date field supports the format dd/MM/yyyy.
Configure Redis producer
Spring Boot provides the default configuration required for the Redis messaging that is sufficient for the messaging.
We will create a configuration class and learn how to customize the default configuration.
Create a RedisProducerConfig class, as shown below.
package com.asbnotebook.config; 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 com.asbnotebook.dto.Student; @Configuration public class RedisProducerConfig { @Bean RedisTemplate<String, Student> redisTemplate(RedisConnectionFactory connectionFactory, Jackson2JsonRedisSerializer<Student> serializer) { RedisTemplate<String, Student> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(connectionFactory); redisTemplate.setDefaultSerializer(serializer); redisTemplate.afterPropertiesSet(); return redisTemplate; } @Bean public Jackson2JsonRedisSerializer<Student> jackson2JsonRedisSerializer() { return new Jackson2JsonRedisSerializer<>(Student.class); } }
Important things to notice here are:
- @Configuration: Indicates that this is a Spring configuration class.
- Jackson2JsonRedisSerializer: We have also created a custom Redis serializer that serializes the Student object.
- Finally, we have customized the RedisTemplate bean by configuring it with the custom Redis serializer to support the Student object as a message body.
Sending the message to Redis server
We will create a utility class that will have a utility method that uses our custom Redis template to send the Student object to the Redis server.
We are also using the @Value annotation to read the name of the topic from the application.properties configuration file.
Finally, we are using the convertAndSend method of the Redis Template to publish the message to the Redis message broker.
package com.asbnotebook.apiagent; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import com.asbnotebook.dto.Student; @Component public class StudentProducer { @Autowired private RedisTemplate<String, Student> redisTemplate; @Value("${redis.student.topic}") private String messageTopic; public void sendMessage(Student student) { System.out.println("Sending Student details: " + student); redisTemplate.convertAndSend(messageTopic, student); } }
Create a REST controller with a POST endpoint.
We will send the JSON request object to this endpoint that will be published to the Redis message broker using the utility class we have created earlier.
package com.asbnotebook.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import com.asbnotebook.apiagent.StudentProducer; import com.asbnotebook.dto.Student; @RestController public class StudentController { @Autowired private StudentProducer studentProducer; @PostMapping("/send-message") public ResponseEntity<String> sendMessage(@RequestBody Student student) { studentProducer.sendMessage(student); return new ResponseEntity<>("Message sent successfully", HttpStatus.OK); } }
Finally, the endpoint will display a successful string message after sending the message to the Redis broker.
Add the Redis configuration properties
Add the below configuration properties to the producer application’s application.properties file under the /src/main/resources/ folder.
spring.redis.host=localhost spring.redis.port=6379 redis.student.topic=studentTopic
We have also specified the Redis configurations by setting the Redis server host, port, and the message topic.
Redis consumer application
Create a consumer application by creating a new Spring boot application. This application will consume the messages from the Redis server that have been published earlier by the producer application.
Creating the Spring Boot consumer application
Create the Spring boot application with similar dependencies to that of the producer application.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency>
Creating the DTO class
Create the Student DTO class, similar to that of the producer application.
We have used the LocalDateDeserializer class to de-serialize the JSON date field.
Also, the date is deserialized with the format: dd/MM/yyyy.
package com.asbnotebook.dto; import java.time.LocalDate; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; import lombok.Getter; import lombok.Setter; import lombok.ToString; @Getter @Setter @ToString public class Student { private Integer id; private String name; @JsonDeserialize(using = LocalDateDeserializer.class) @JsonFormat(pattern = "dd/MM/yyyy") private LocalDate dob; }
Configure Redis consumer
Create a Redis consumer configuration class to customize the consumer configurations.
package com.asbnotebook.config; import org.springframework.beans.factory.annotation.Value; 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.listener.PatternTopic; import org.springframework.data.redis.listener.RedisMessageListenerContainer; import org.springframework.data.redis.listener.adapter.MessageListenerAdapter; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import com.asbnotebook.apiagent.StudentConsumer; import com.asbnotebook.dto.Student; @Configuration public class RedisListenerConfig { @Value("${redis.student.topic}") private String studentTopic; @Bean public RedisMessageListenerContainer listenerContainer(MessageListenerAdapter listenerAdapter, RedisConnectionFactory connectionFactory) { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(connectionFactory); container.addMessageListener(listenerAdapter, new PatternTopic(studentTopic)); return container; } @Bean public MessageListenerAdapter listenerAdapter(StudentConsumer consumer) { MessageListenerAdapter messageListenerAdapter = new MessageListenerAdapter(consumer); messageListenerAdapter.setSerializer(new Jackson2JsonRedisSerializer<>(Student.class)); return messageListenerAdapter; } @Bean RedisTemplate<String, Student> redisTemplate(RedisConnectionFactory connectionFactory, Jackson2JsonRedisSerializer<Student> serializer) { RedisTemplate<String, Student> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(connectionFactory); redisTemplate.setDefaultSerializer(serializer); redisTemplate.afterPropertiesSet(); return redisTemplate; } @Bean public Jackson2JsonRedisSerializer<Student> jackson2JsonRedisSerializer() { return new Jackson2JsonRedisSerializer<>(Student.class); } }
Important points to notice here are:
- RedisMessageListenerContainer: The bean is helpful to configure the Redis topic that the consumer application should consume.
- MessageListenerAdapter: This bean is configured with the custom Jackson2JsonRedisSerializer serializer. This class also expects us to define a handleMethod() that consumes the Redis message.
- We also have created a custom Jackson2JsonRedisSerializer bean to support the student object. This bean configuration is similar to that of the producer application.
- We have also created a custom RedisTemplate Bean.
Consuming the message from Redis
Create a StudentConsumer component class. This class will be our Redis consumer class.
By default, we have to create a method with the name handleMessage. This method will listen to the topics that are specified in the configuration.
Also, the method parameter should contain the object type that it consumes. In our example, the method accepts the Student object.
package com.asbnotebook.apiagent; import org.springframework.stereotype.Component; import com.asbnotebook.dto.Student; @Component public class StudentConsumer { public void handleMessage(Student student) { System.out.println("Consumer> " + student); } }
Adding the Redis consumer configuration properties
Add the below configuration properties to the application.properties file under the /src/main/resources/ folder.
The configuration file contains the Redis server host, port details, which are similar to that of the producer application.
The configured topic here is the topic name that is used by the producer application while publishing the message.
spring.redis.host=localhost spring.redis.port=6379 redis.student.topic=studentTopic server.port=8081
We have also updated the server port(8081) of the consumer application to avoid any conflict with the producer application.
Testing the application
Start the Spring Boot producer and consumer applications.
Send the student details by sending the proper JSON request to the /send-message POST endpoint.

We can also observe that the message was sent successfully to the message broker.

We can also observe published messages to the studentTopic on the Redis server.

Finally, the consumer consumes the message and prints the student object as shown below.

Conclusion
In this article, we learned how to use Redis messaging with Spring Boot.
We also learned how to create a publish/subscribe application by creating producer and consumer Spring Boot applications.
Finally, the example code is available on GitHub.