Redis_发布订阅(Spring Boot)

目录

  前言

  生产者和消费者

  发布和订阅

     Java实现

  注意

     转至 http://www.tianmaying.com/tutorial/springboot-redis-message

前言

利用Spring Data对Redis的支持来实现消息的发布订阅机制。
使用StringRedisTemplate来发布一个字符串消息,同时基于MessageListenerAdapter使用一个POJO来订阅和响应该消息。
Receiver类将会被注册为一个消息监听者时。给Receiver的构造函数通过@AutoWired标注注入了一个CountDownLatch实例,当接收到消息时,调用cutDown()方法。
Spring Data Redis提供基于Redis发送和接收消息的所有需要的组件,需要配置如下:
a.一个连接工厂(connection factory)
b.一个消息监听者容器(message listener container)
c.一个Redis的模板(redis template)
d.将Receiver注册给消息监听者容器。连接工厂将两者连接起来,使得它们可以通过Redis服务器通信。

实现

  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> 
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.8.2</version>
            <scope>test</scope>
        </dependency>        
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
View Code

     application.properties

#spring.redis.database=0
spring.redis.host=192.168.1.10
#spring.redis.password=  Login password of the redis server.
#spring.redis.pool.max-active=8
#spring.redis.pool.max-idle=8
#spring.redis.pool.max-wait=-1
#spring.redis.pool.min-idle=0
spring.redis.port=6379
#spring.redis.sentinel.master=  Name of Redis server.
#spring.redis.sentinel.nodes=  Comma-separated list of host:port pairs.
#spring.redis.timeout=0
View Code

     Receiver.java

package com.dengzy.springboot.redis;

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 + ">");
        //当接收到消息时,调用cutDown()方法。
        latch.countDown();
    }
}
View Code

     app.java

package com.dengzy.springboot;
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;

import com.dengzy.springboot.redis.Receiver;

@SpringBootApplication
public class App {

    private static final Logger LOGGER = LoggerFactory.getLogger(App.class);

    //listenerAdapter方法中定义的Bean注册为一个消息监听者,它将监听chat主题的消息。
    @Bean
    RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
            MessageListenerAdapter listenerAdapter) {

        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.addMessageListener(listenerAdapter, new PatternTopic("chat"));

        return container;
    }
    //MessageListenerAdapter使用一个POJO来订阅和响应该消息。
    @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);
    }
    //StringRedisTemplate来发送键和值均为字符串的消息。
    @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);
    }
}
View Code

     sendMsg.java

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public class SendMessage {
    private static Logger logger = LoggerFactory.getLogger(SendMessage.class);
    
    public static final String CHANNEL_NAME = "chat";

    public static void main(String[] args) throws Exception {

        JedisPoolConfig poolConfig = new JedisPoolConfig();

        JedisPool jedisPool = new JedisPool(poolConfig, "192.168.1.10", 6379, 0);
        
        for(int i=0;i<10;i++){
             try {
                jedisPool.getResource().publish(CHANNEL_NAME, "hello" + i);
            } catch (Exception e) {
                logger.error("Subscribing failed." + e.getMessage());
            }           
        }
 
    }
}
View Code

 

posted on 2016-08-23 18:52  dengzy  阅读(550)  评论(0编辑  收藏  举报