【前言】Spring NoSQL来了~。原文链接 http://spring.io/guides/gs/messaging-redis/
【目标】在这里,你将使用Spring Date Redis通过Redis发布和订阅消息
【准备工作】
<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>
在任何基于消息的应用中,都有消息发布器和消息接收机。这里为接收消息实现一个消息接收机类
package hello; 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(); } }
为了做个示范,他用构造器组装一个倒计时器。在这种方式下,当收到消息时他会发送信号。
注册监听器并且发送消息
Spring Data Redis 提供了收发消息的所有机制。不过你需要做一下配置:
连接工厂
消息监听容器
Redis模板
你将要使用Redis模板发消息,然后在消息监听容器中注册一个Receiver类的监听器来收消息。连接工厂作为消息收发双方的驱动,使Redis模板和监听器连接到Redis服务上。
本例使用Spring Boot默认的RedisConnectionFactory,这是一个基于Jedis的JedisConnectionFactory实例。连接工厂将会注入Redis模板和监听器容器。
package hello; 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 Application { private static final Logger LOGGER = LoggerFactory.getLogger(Application.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(Application.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); } }
在listenAdapter方法中定义的bean注册为消息监听器(指第二个@Bean listenAdapter就是监听器)。消息监听器容器定义在container中并在此定义为监听“chat”主题(指第一个@Bean container就是容器)。因为Receiver类是一个POJO,它需要在消息监听器中展开,这个监听器要实现MessageListerner接口,这样才能符合addMessageListerner()定义中对参数类型的要求。消息监听器同样配置了Receiver,这样一旦收到消息就在Receiver上调用receiveMessage()方法。(MessageListenerAdapter(receiver, "receiveMessage"); 这个方法中,第二个参数就是回调函数名)
连接工厂和容器bean是实现监听所需要的。为了发消息,你还需要一个Redis模板。这里Redis模板被配置成一个StringRedisTemplate类的Bean,这个类实现RedisTemplate接口。RedisTemplate接口处理Redis的使用,通常Redis中的Key Value都是String对象。
main()方法创建了一个简单的应用上线文,剔除除此之外的所有东西。应用上线文启动消息监听器容器,然后容器bean启动监听消息。main()方法再从应用上下文中检索StringRedisTemplate bean,然后用Redis模板在“chat”话题上发送一条“Hello from Redis!”消息。最后main()方法关闭应用上下文,应用完成。
【小结】实现本节功能需要4个组件:接收机、发送机、接收机容器、Redis模板。
<span style="font-size:14px;">convertAndSend(),那么Receiver的响应方法就会做出反应。</span>