如果发布的redis是当前springboot配置的Redis,那就直接进行订阅!

导入maven

<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </dependency>

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;


@Configuration
public class RedisSubscriber extends JedisPubSub{


@Bean
    public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory connectionFactory) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        //订阅了一个叫chat 的通道
        container.addMessageListener(new MessageListener(){
            @Override
            public void onMessage(Message message, byte[] pattern) {
                String msg = new String(message.getBody());
                System.out.println(new String(pattern) + "主题发布:" + msg);
                //获取到通道消息进行解析msg,并处理
                
            }
        }, new PatternTopic("xxx"));  //xxx:具体的通道名。如果是多个通道,那就直接复制setConnectionFactory就好
        return container;
    }


}

如果订阅的消息不是,当前配置的Redis,那就需要从新起一个线程,不然直接获取连接,会导致线程阻塞,因为redis本身是但线程的。

port org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisPubSub;


@Configuration
public class RedisSubscriber extends JedisPubSub{


    //在yaml里面的自定义的redis的链接进行获取

    @Value("${video.host}")  //ip
    private String host;

    @Value("${video.port}")  //端口
    private String port;


    @Value("${video.password}")  //密码
    private String password;


@Bean
    public void redisMessageListenerContainer() {
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(100);
        jedisPoolConfig.setMaxWaitMillis(10000);
        jedisPoolConfig.setMinIdle(8);
        jedisPoolConfig.setMaxTotal(500);
        jedisPoolConfig.setJmxEnabled(true);
        jedisPoolConfig.setTestOnBorrow(true);
        jedisPoolConfig.setTestOnReturn(true);
        JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, Integer.valueOf(port), 100000, password);
        SubThread subThread=new SubThread(jedisPool);
        subThread.start();
   }

}
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

public class SubThread extends Thread {

    private final JedisPool jedisPool;
    private final Subscriber subscriber = new Subscriber();

    //订阅通道
    private final String Channel1 = "Channel1";
    private final String Channel2= "Channel2";

    public SubThread(JedisPool jedisPool) {
        super("SubThread");
        this.jedisPool = jedisPool;
    }

    @Override
    public void run() {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();   //取出一个连接
            jedis.subscribe(subscriber, Channel1,Channel2) 【通道可配置单个或者多个,底层源码有体现】
        } catch (Exception e) {
            System.out.println(e);
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }
    }
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.JedisPubSub;


@Component
public class  Subscriber extends JedisPubSub {

    // 这样写是因为 service无法注入的原因

    public static XxxxService xxxxxService;

    @Autowired
    public void setSenderService(XxxxService xxxxxService){
        Subscriber.XxxxService = xxxxxService;
    }

    

    public Subscriber(){}
    @Override
    public void onMessage(String channel, String message) {       //收到消息会调用
        //视频告警
        //System.out.println("【"+channel + "】主题发布:" + message);
        if("Channel1".equals(channel)){
           //具体逻辑编写
        }
    }

}

或者:

Redis 消息发布订阅 与 Spring boot 使用快速入门_redis消息订阅与发布springboot- 

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * Redis 消息订阅-消息监听器,当收到阅订的消息时,会将消息交给这个类处理
 * <p>
 * 1、可以直接实现 MessageListener 接口,也可以继承它的实现类 MessageListenerAdapter.
 * 2、自动多线程处理,打印日志即可看出,即使手动延迟,也不会影响后面消息的接收。
 *
 * @author wangMaoXiong
 * @version 1.0
 * @date 2022/5/21 16:00
 */
@Component
@Slf4j
public class RedisSubListener implements MessageListener {

    // 直接从容器中获取
    @Resource
    private RedisTemplate redisTemplate;
    /**
     * 监听到的消息必须进行与发送时相同的方式进行反序列
     * 1、订阅端与发布端 Redis 序列化的方式必须相同,否则会乱码。
     *
     * @param message :消息实体
     * @param pattern :匹配模式
     */
    @Override
    public void onMessage(Message message, byte[] pattern) {
        // 消息订阅的匹配规则,如 new PatternTopic("basic-*") 中的 basic-*
        String msgPattern = new String(pattern);
        // 消息所属的通道,可以根据不同的通道做不同的业务逻辑
        String channel = (String) redisTemplate.getStringSerializer().deserialize(message.getChannel());
        // 接收的消息内容,可以根据自己需要强转为自己需要的对象,但最好先使用 instanceof 判断一下
        Object body = redisTemplate.getValueSerializer().deserialize(message.getBody());

        // 收到 Redis 订阅消息: channel=basic-service body=flushDb pattern=basic-*
        // 收到 Redis 订阅消息: channel=memoryCache body=flushAll pattern=memoryCache
        log.info("收到 Redis 订阅消息: channel={} body={} pattern={} ", channel, body, msgPattern);

        // 手动延迟,模拟数据处理
        log.info("------------数据处理完成.......");
    }
}
package com.spiceIngredients.web.monitoring.redis;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisPubSub;

import javax.annotation.Resource;


@Configuration
public class RedisSubscriber{


    @Resource
    private RedisSubListener redisSubListener;


    @Bean
    public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        // 设置连接工厂,RedisConnectionFactory 可以直接从容器中取,也可以从 RedisTemplate 中取
        container.setConnectionFactory(connectionFactory);
        // 订阅名称叫 memoryCache 的通道, 类似 Redis 中的 subscribe 命令
        container.addMessageListener(redisSubListener, new ChannelTopic("memoryCache"));
        // 订阅名称以 'basic-' 开头的全部通道, 类似 Redis 的 pSubscribe 命令
        container.addMessageListener(redisSubListener, new PatternTopic("basic-*"));
        return container;
    }


}