redis的消息发布订阅实现

72 阅读2分钟

文章目录


前言

一般项目中都会使用redis作为缓存使用,加速用户体验,实现分布式锁等等,redis可以说为项目中的优化,关键技术实现立下了汗马功劳.今天带来它的另一个功能,实现简单的消息发布订阅~,也就是说如果是简单的消息队列,首先是不需要我们自己实现的,其次很简单的那种,也无需引入mq相关的东西;


一、创建好springboot项目,引入核心依赖

      <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-redis</artifactId>
            <version>1.4.7.RELEASE</version>
        </dependency>
         <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

二、使用步骤

1.

自定义一个消息接受类

代码如下(示例):

/**
 * @ClassName: MyReceiver
 */
@Component
@Slf4j
public class MyReceiver implements MessageListener {
    @Override
    public void onMessage(Message message, byte[] pattern) {
        log.info("接受消息的通道:{}",new String(message.getChannel()));
        log.info("接受到的消息:{}",new String(message.getBody()));
//        Student student = JSONUtil.toBean(new String(message.getBody()), Student.class);
//       log.info("年龄:{}",student.getAge());
    }
}

2.声名一个消息配置类

代码如下(示例):

/**
 * @ClassName: ListenerConfig
 */
@Component
public class ListenerConfig {

    @Autowired
    MyReceiver myReceiver;

    @Bean
    RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory, MessageListenerAdapter listenerAdapter) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        // 声名了两个接受消息的通道(主题)
        // 将myReceiver与消息通道绑定
        container.addMessageListener(listenerAdapter, new PatternTopic("redis_channel"));
        container.addMessageListener(listenerAdapter, new PatternTopic("redis_channel2"));
        return container;
    }

    //使用消息监听器容器注册Receiver,以便它将接收消息(监听onMessage方法)
    // 将上面的myReceiver注入到当前监听处理器中
    @Bean
    MessageListenerAdapter listenerAdapter() {
        return new MessageListenerAdapter(myReceiver, "onMessage");
    }
}

3.编写一个测试类

@SpringBootTest
class RedisTest {

    @Autowired
    StringRedisTemplate redisTemplate;

    @Autowired
    MyReceiver myReceiver;

    @Autowired
    ObjectMapper objectMapper;

    @Test
    void ss() throws JsonProcessingException {
        Student student = new Student();
        student.setAge(12);
        student.setId(11);
        redisTemplate.convertAndSend("redis_channel", JSONUtil.toJsonStr(student));
        redisTemplate.convertAndSend("redis_channel1", objectMapper.writeValueAsString("哈哈哈哈"));
        redisTemplate.convertAndSend("redis_channel2", objectMapper.writeValueAsString("嘻嘻嘻"));
    }

}

运行结果

代码中用的通讯实体,注意实现 Serializable 序列化

/**
 * 学生类
 *
 * @author ming
 */
public class Student implements Serializable {

    private int id;

    private String name;

    private int age;

    //一个学生有多个电话号码
    List tels = new ArrayList();

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public List getTels() {
        return tels;
    }

    public void setTels(List tels) {
        this.tels = tels;
    }



    public static class Tel {

        private String name;

        private String tel;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getTel() {
            return tel;
        }

        public void setTel(String tel) {
            this.tel = tel;
        }


    }
}

总结

可以看到

  1. 实现了消息的发布,以及消息的订阅接受消息

  2. 我在测试类中 RedisTest 发布了三条消息,但是在 myReceiver仅仅接受到了两条消息,是因为我在 ListenerConfig 配置类中仅仅给myReceiver 绑定了两条消息通道的原因

  3. myReceiver的注释可以打开,可以接收到消息并且可以转换为实体,接受到消息后可以任意处理

本文转自 jimolvxing.blog.csdn.net/article/det…,如有侵权,请联系删除。