springboot中使用redis的发布与订阅

该文展示了如何在SpringBoot中配置RedisTemplate,包括使用Jackson2JsonRedisSerializer进行序列化,并创建Redis消息监听器来处理不同主题的消息。同时,文章还包含了Dto类用于数据传输,以及消息的发布和接收方法。
摘要由CSDN通过智能技术生成

1、Configuration配置

@Configuration
@ComponentScan({"xxxxx.core.service.redis"})
public class xxxxRedisConfig {
    @Bean
    @SuppressWarnings("all")
    public RedisTemplate<String, Object> xxxRedisTemplate(
            RedisConnectionFactory factory
    ) {
        //由于源码autoConfig中是<Object, Object>,开发中一般直接使用<String,Object>
        RedisTemplate<String, Object> template = new RedisTemplate();
        template.setConnectionFactory(factory);

        //Json序列化配置
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        //String的序列化
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();

        //key采用string的序列化
        template.setKeySerializer(stringRedisSerializer);
        //hash的key采用string的序列化
        template.setHashKeySerializer(stringRedisSerializer);
        //value序列化采用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);
        //hash的value序列化方式采用jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }

    /**
     * Redis消息监听器容器
     * 这个容器加载了RedisConnectionFactory和消息监听器
     * 可以添加多个监听不同话题的redis监听器,只需要把消息监听器和相应的消息订阅处理器绑定,该消息监听器
     * 通过反射技术调用消息订阅处理器的相关方法进行一些业务处理
     *
     * @param redisConnectionFactory 连接工厂
     * @param adapter                适配器
     * @return redis消息监听容器
     */
    @Bean
    @SuppressWarnings("all")
    public RedisMessageListenerContainer xxxRedisMessageListenercontainer(
            RedisConnectionFactory redisConnectionFactory,
            xxxRedisMessageListener listener,
            xxxPrintMessageReceiver printMessageReceiver
            //MessageListenerAdapter adapter
    ) {

        final String xxxWebsocket = "xxxWebsocket"; // 订阅主题
        final String TOPIC_NAME2 = "TEST_TOPIC2"; // 订阅主题
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        // 监听所有库的key过期事件
        container.setConnectionFactory(redisConnectionFactory);
        // 所有的订阅消息,都需要在这里进行注册绑定,new PatternTopic(TOPIC_NAME1)表示发布的主题信息
        // 可以添加多个 messageListener,配置不同的通道
        container.addMessageListener(listener, new PatternTopic(xxxWebsocket));
        container.addMessageListener(xxxMessageListenerAdapter( printMessageReceiver), new PatternTopic(TOPIC_NAME2));

        /**
         * 设置序列化对象
         * 特别注意:1. 发布的时候需要设置序列化;订阅方也需要设置序列化
         *         2. 设置序列化对象必须放在[加入消息监听器]这一步后面,否则会导致接收器接收不到消息
         */
        Jackson2JsonRedisSerializer seria = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        seria.setObjectMapper(objectMapper);
        container.setTopicSerializer(seria);

        return container;
    }

    /**
     * 这个地方是给messageListenerAdapter 传入一个消息接受的处理器,利用反射的方法调用“receiveMessage”
     * 也有好几个重载方法,这边默认调用处理器的方法 叫OnMessage
     *
     * @param printMessageReceiver
     * @return
     */
    @Bean
    public MessageListenerAdapter xxxMessageListenerAdapter(xxxPrintMessageReceiver printMessageReceiver) {
        MessageListenerAdapter receiveMessage = new MessageListenerAdapter(printMessageReceiver, "xxxReceiveMessage");

        Jackson2JsonRedisSerializer seria = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        seria.setObjectMapper(objectMapper);
        receiveMessage.setSerializer(seria);
        return receiveMessage;
    }
}
@Slf4j
@Component
public class xxxPrintMessageReceiver{


    public void xxxReceiveMessage(xxxRedisMessageDto messageDto , String channel) {

        // 接收的topic
        log.info("channel:" + channel);

        log.info("message:" + messageDto.getTitle());
    }
}

2、 消息接收类

@Slf4j
@Component
public class xxxRedisMessageListener implements MessageListener {
    @Resource
    private RedisTemplate xxxRedisTemplate;

    @Override
    public void onMessage(Message message, byte[] bytes) {
        // 接收的topic
        //log.info("channel:" + new String(bytes));

        //序列化对象(特别注意:发布的时候需要设置序列化;订阅方也需要设置序列化)
        xxxRedisMessageDto messageDto = (xxxRedisMessageDto) xxxRedisTemplate.getValueSerializer().deserialize(message.getBody());
        //log.info(messageDto.getData()+","+messageDto.getContent());
        xxxWebsocket xxxWebsocket = new xxxWebsocket();
        String msgtxt = JSONSerializer.serialize(messageDto.getMepeprobleminfo());
        xxxWebsocket.sendMessageByUser(messageDto.getMepeprobleminfo().getWorkcenterid(),msgtxt);
    }
}

3、 消息发布类

 private final String TOPIC_NAME1 = "xxxWebsocket"; // 订阅主题
public void xxxRedisConvertAndSend(Object data) {
        try {
            // 发布消息
            xxxRedisMessageDto dto = new xxxRedisMessageDto();
            dto.setXxx((xxxXXXxxxEntity) data);
            dto.setTitle("异常信息");
            dto.setContent("异常信息");
            xxxRedisTemplate.convertAndSend(TOPIC_NAME1, dto);
        } catch (Throwable e) {
            log.error("消息发布", e);
        }
    }

4、Dto

@AllArgsConstructor
@NoArgsConstructor
@Data
public class xxxRedisMessageDto implements Serializable {

    private String title;
    private String content;
    private Object data;
    private xxxXXXxxxEntity xxx;

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值