SpringBoot和redis发布订阅

前言:

发布订阅是消息的一种常用模式。例如,在企业分配任务之后 ,可以通过邮件、 短信或者微信
通知到相关的责任人,这就是一种典型的发布订阅模式。首先是 Redis 提供一个渠道,让消息能够发
送到这个渠道上 ,而多个系统可以监听这个渠道, 如短信、微信和邮件系统都可以监昕这个渠道,
当一条消息发送到渠道,渠道就会通知它的监昕者,这样短信、微信和邮件系统就能够得到这个渠
道给它们的消息了,这些监听者会根据自己的需要去处理这个消息,于是我们就可以得到各种各样
的通知了 。 其原理如下图:

本次测试为了方便测试,发布和订阅都在一个工程中,代码如下:

1.导入依赖

<!--我使用的是父版本是2.0.4-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

   <dependencies>

       <!--springBoot-web用于建立restful接口测试发布-->
       <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.0.0.M7</version>
        </dependency>

       <!--加入redis的启动器-->
       <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <version>1.5.7.RELEASE</version>
       </dependency>

   </dependencies>

2.application.properties配置如下

server.port=9999
#redis
spring.redis.port=6379
spring.redis.jedis.pool.min-idle=5
spring.redis.jedis.pool.max-active=10
spring.redis.jedis.pool.max-idle=10
spring.redis.jedis.pool.max-wait=2000ms
spring.redis.host=localhost
spring.redis.timeout=1000ms

3.redis订阅方

为了接收 Redis 渠道发送过来的消息,我们先定义一个消息监听器( MessageListener ),代码如下:

/**
 * 为了接收 Redis 渠道发送过来的消息,我们先定义一个消息监听器( MessageListener ),代码
 */
@Component
public class RedisSubscribe implements MessageListener {

    /**
     * 这里的 onMessage 方法是得到消息后的处理方法, 其中 message 参数代表 Redis 发送过来的消息,
     * pattern是渠道名称,onMessage方法里打印 了它们的内容。这里因为标注了 @Component 注解,所以
     * 在 Spring Boot 扫描后,会把它自动装配到 IoC 容器中 ,监听着对象RedisMessageListener会自动
     * 将消息进行转换。
     * @param message
     * @param pattern
     */
    @Override
    public void onMessage(Message message, byte[] pattern) {
        //消息体
        String body = new String(message.getBody());
        //渠道名称
        String topic = new String(pattern);
        System.out.println("消息体:"+body);
        System.out.println("渠道名称:"+topic);
    }
}

接着我们在 Spring Boot 的启动文件中配置其他信息,让系统能够监控 Redis 的消息,代码如下:

 

/**
 * @Author: Lee
 * @Date: 2018/11/7 13:25
 * @Description:
 */
@Configuration
public class RedisSubConfig {

    /**
     * 这里 RedisTemplate 和 RedisConnectionFactory 对象都是 Spring Boot 自动创建的,所以这里只是
     * 把它们注入进来,只需要使用@Autowired 注解即可 。然后定义了一个任务池 ,并设置了任务池大小
     * 为 2 0 ,这样它将可 以运行线程 ,井进行阻塞,等待 Redis 消息的传入。接着再定义了一个 Redis消息
     * 监听的容器 RedisMessageListenerContainer,并且往容器设置了 Redis 连接工厂和指定运行消息的线
     * 程池,定义了接收“ topicl ”渠道的消息,这样系统就可以监听 Redis 关于“ topicl "渠道的消息了 。
     */



    /** redis 连接工厂 */
    @Resource
    private RedisConnectionFactory redisConnectionFactory;

    /**
     *     Redis消息监听器
     */
    @Resource
    private MessageListener redisMsgListener;

    //任务池
    private ThreadPoolTaskScheduler taskScheduler;

    /**
     * 创建任务池,运行线程等待处理redis的消息
     */
    @Bean
    public ThreadPoolTaskScheduler initTaskScheduler() {
        if (null != taskScheduler) {
            return taskScheduler;
        }
        taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setPoolSize(20);
        return taskScheduler;
    }

    /**
     * 定义redis的监听器
     * @return 监听容器
     */
    @Bean
    public RedisMessageListenerContainer initRedisContainer() {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        //Redis连接工厂
        container.setConnectionFactory(redisConnectionFactory);
        //设置运行任务的线程池
        container.setTaskExecutor(initTaskScheduler());
        //定义监听渠道,名称为topic1
        Topic topic = new ChannelTopic("topic1");
        //使用监听器监听Redis的消息
        container.addMessageListener(redisMsgListener, topic);
        return container;
    }
}

4.redis发布方

创建一个控制器和处理器,代码如下:

@RestController
public class TestController {

  
    @Resource
    private RedisTemplate redisTemplate;

    @GetMapping(value = "/testPush", produces = "application/json;charset=utf-8")
    public void testPush(String body) {
        /**
         * 使用redisTemplate的convertAndSend()函数,
         * String channel, Object message
         * channel代表管道,
         * message代表发送的信息
         */
        redisTemplate.convertAndSend("topic1", body);
    }
}

 这样就实现了异步的发布消息,订阅消息了。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
可以回答这个问题。以下是一个简单的 Spring Boot 实现 Redis 发布订阅的例子: 1. 首先,在 pom.xml 文件中添加 Redis 和 Spring Data Redis 的依赖: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> ``` 2. 在 application.properties 文件中配置 Redis 的连接信息: ``` spring.redis.host=127...1 spring.redis.port=6379 ``` 3. 创建一个 Redis 发布者: ``` @Component public class RedisPublisher { @Autowired private RedisTemplate<String, Object> redisTemplate; public void publish(String channel, Object message) { redisTemplate.convertAndSend(channel, message); } } ``` 4. 创建一个 Redis 订阅者: ``` @Component public class RedisSubscriber { @Autowired private MessageListenerAdapter messageListenerAdapter; @PostConstruct public void init() { redisTemplate.execute((RedisCallback<Void>) connection -> { connection.subscribe(messageListenerAdapter, "channel"); return null; }); } @PreDestroy public void destroy() { redisTemplate.execute((RedisCallback<Void>) connection -> { connection.unsubscribe(); return null; }); } } ``` 5. 创建一个消息监听器: ``` @Component public class MessageListenerAdapter extends org.springframework.data.redis.listener.adapter.MessageListenerAdapter { @Override public void onMessage(Message message, byte[] pattern) { String channel = new String(message.getChannel()); String messageBody = new String(message.getBody()); System.out.println("Received message: " + messageBody + " from channel: " + channel); } } ``` 6. 在需要发布消息的地方调用 RedisPublisher 的 publish 方法: ``` @Autowired private RedisPublisher redisPublisher; redisPublisher.publish("channel", "Hello, Redis!"); ``` 这样,当有消息发布到 "channel" 频道时,RedisSubscriber 中的 MessageListenerAdapter 就会收到消息并打印出来。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

技术武器库

一句真诚的谢谢,胜过千言万语

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值