brief introduction
Today, the senior students will teach you how to use Spring Data's support for Redis to realize the publish and subscribe mechanism of messages. Publish and subscribe is a typical asynchronous communication model, which can fully decouple the publisher and subscriber of messages. In our example, we will use StringRedisTemplate to publish a string message, and use a POJO based on messagelistener adapter to subscribe to and respond to messages.
Tips
In fact, RedisRedis not only provides a NoSQL database, but also provides a message system.
Environmental preparation
Development environment:
- IDE+Java environment (JDK 1.7 or above)
- Maven 3.0 + (Eclipse and Idea IntelliJ are built-in. If you use IDE and do not use command-line tools, you can not install it)
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.tianmaing</groupId> <artifactId>redis-message</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>redis-message</name> <description>Demo of message processing by redis</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.2.5.RELEASE</version> <relativePath/> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-redis</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
By configuring the Spring Boot starter Redis dependency, the Spring Boot support for Redis is introduced.
Create the recipient of Redis message
In any message based application, there are message publishers and message receivers (or called message subscribers). To create a message receiver, we only need a common POJO and define a message receiving method in the POJO:
package com.tianmaying.springboot.redisdemo; import java.util.concurrent.CountDownLatch; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; public class Receiver { private static final Logger LOGGER = LoggerFactory.getLogger(Receiver.class); private CountDownLatch latch; @Autowired public Receiver(CountDownLatch latch) { this.latch = latch; } public void receiveMessage(String message) { LOGGER.info("Received <" + message + ">"); latch.countDown(); } }
When the Receiver class will be registered as a message listener. The method of processing messages can be named arbitrarily, and we have considerable flexibility.
We inject a CountDownLatch instance into the constructor of the Receiver through the @ AutoWired annotation. When a message is received, we call the cutDown() method.
Register listeners and send messages
Spring Data Redis provides all required components for sending and receiving messages based on Redis. We only need to configure three things:
- A connection factory
- A message listener container
- A Redis template
We will send messages through the Redis template and register the Receiver with the message listener container. The connection factory connects the two so that they can communicate through the Redis server. How to connect? We can inject the connection factory instance into the listener container and Redis template respectively.
package com.tianmaying.springboot.redisdemo; import java.util.concurrent.CountDownLatch; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.listener.PatternTopic; import org.springframework.data.redis.listener.RedisMessageListenerContainer; import org.springframework.data.redis.listener.adapter.MessageListenerAdapter; @SpringBootApplication public class App { private static final Logger LOGGER = LoggerFactory.getLogger(App.class); @Bean RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory, MessageListenerAdapter listenerAdapter) { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(connectionFactory); container.addMessageListener(listenerAdapter, new PatternTopic("chat")); return container; } @Bean MessageListenerAdapter listenerAdapter(Receiver receiver) { return new MessageListenerAdapter(receiver, "receiveMessage"); } @Bean Receiver receiver(CountDownLatch latch) { return new Receiver(latch); } @Bean CountDownLatch latch() { return new CountDownLatch(1); } @Bean StringRedisTemplate template(RedisConnectionFactory connectionFactory) { return new StringRedisTemplate(connectionFactory); } public static void main(String[] args) throws InterruptedException { ApplicationContext ctx = SpringApplication.run(App.class, args); StringRedisTemplate template = ctx.getBean(StringRedisTemplate.class); CountDownLatch latch = ctx.getBean(CountDownLatch.class); LOGGER.info("Sending message..."); template.convertAndSend("chat", "Hello from Redis!"); latch.await(); System.exit(0); } }
For the connection project, we use the Spring Boot default RedisConnectionFactory, which is the JedisConnectionFactory implementation provided by the Jedis Redis library.
We register the Bean defined in the listenerAdapter method as a message listener, which will listen to the messages of the chat topic.
Because the Receiver class is a POJO, it should be wrapped in a message listener adapter (implementing the MessageListener interface) so that it can be added to the connection factory by the addMessageListener method of the listener container redismessagelistener container. With this adapter, when a message arrives, it will call the receivemessage() ` method to respond.
It's that simple. After configuring the connection factory and the message listener container, you can listen to messages!
Sending messages is easier. We use StringRedisTemplate to send messages with both keys and values as strings. In the main() method, we create a Context of the Spring application, initialize the message listener container, and start listening for messages. Then get the instance of StringRedisTemplate and send a message to the chat topic. We see that the message can be successfully received and printed, done!