【Spring】官网教程阅读笔记(五):Redis消息

【前言】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>


创建Redis消息接收器

在任何基于消息的应用中,都有消息发布器和消息接收机。这里为接收消息实现一个消息接收机类

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();
    }
}

这个接收机是一个简单的POJO,其中定义了一个方法接收消息。之后你会看到,当你把这个接收机Receiver注册为消息监听器之后,你可以任意命名消息处理方法。

为了做个示范,他用构造器组装一个倒计时器。在这种方式下,当收到消息时他会发送信号。

注册监听器并且发送消息

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()方法关闭应用上下文,应用完成。

Redis参考链接http://pivotal.io/big-data/pivotal-big-data-suite

【小结】实现本节功能需要4个组件:接收机、发送机、接收机容器、Redis模板。

  • 其中接收机单独实现一个类Receiver,用注解@Autowired标记构造器表明该类对象会被Spring依赖注入机制自动装配在需要的地方。
  • 关于@Autowired注解,它被应用在构造器,域,setter和其他配制方法上(如返回类实例的工厂方法等)。在一个@Bean中,最多允许一个构造器使用@Autowired,而这个被标注的构造器不必为public。如果标注到域上,这个域会在构造器之后配制方法之前被装配,同样这个域可以不是public的,并且可以有多个域被注解。配置方法可以有任意名字和任意数目参数,Spring会在其内部检索合适的bean来装配方法的参数,配制方法同样不需要是public的;setter方法是配制方法的特例。
  • 发送机,接收机容器在application中使用@Bean注解,没有单独定义一个类。容器需要绑定到连接工厂上,然后添加必要的监听器;监听器需要绑定接收对象的回调函数。绑定关系看起来像这样:Receiver->ListenningAdapter->container->RedisConnectionFactory
  • main()方法里面直接操作RedisTemplate,在这个RedisTemplate对象里自动绑定了RedisConnectionFactory,只要在Template上触发了发送
    <span style="font-size:14px;">convertAndSend(),那么Receiver的响应方法就会做出反应。</span>
  • 最后关于ApplicationContext上引用@Bean,用他的实例ctx.getBean(Class)就可以获得。

你可能感兴趣的:(redis,spring,消息交换)