Springamqp rabbit json ReturnCallback ConfirmCallback

本文介绍了如何在Spring Boot应用中集成RabbitMQ,使用Jackson2JsonMessageConverter进行JSON消息转换,并实现ConfirmCallback和ReturnCallback,确保消息的发送与接收确认,以及异常处理。示例代码展示了配置RabbitTemplate、创建监听容器工厂以及发送与接收消息的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

package com.study.soufang.rabbit.a003.springboot.rabbitmq;

import org.springframework.amqp.rabbit.core.RabbitTemplate.ConfirmCallback;
import org.springframework.amqp.rabbit.support.CorrelationData;

public class MyConfirmCallback implements ConfirmCallback {

    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        // TODO Auto-generated method stub
        System.out.println("correlationData:"+correlationData+",ACK:"+ack+",Cause:"+cause);
    }

}
--------------------------------------------------------------------------------------------------------------------------------------------

package com.study.soufang.rabbit.a003.springboot.rabbitmq;

import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.boot.autoconfigure.amqp.RabbitProperties;
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyRabbitConfiguration {

    private RabbitProperties properties;
    MessageConverter messageConverter = new Jackson2JsonMessageConverter();
    @Bean
    @ConditionalOnMissingBean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        PropertyMapper map = PropertyMapper.get();
        RabbitTemplate template = new RabbitTemplate(connectionFactory);
        template.setConfirmCallback(new MyConfirmCallback());
        template.setReturnCallback(new MyReturnCallback());
        template.setMessageConverter(messageConverter);
        //mandatory 默认为FALSE,如果exchange根据自身类型和消息routeKey无法找到一个符合条件的queue,会直接将消息扔掉
        template.setMandatory(true);
        return template;
    }
    
    
    @Bean(name = "rabbitListenerContainerFactory")
    @ConditionalOnMissingBean(name = "rabbitListenerContainerFactory")
    @ConditionalOnProperty(prefix = "spring.rabbitmq.listener", name = "type", havingValue = "simple", matchIfMissing = true)
    public SimpleRabbitListenerContainerFactory simpleRabbitListenerContainerFactory(
            SimpleRabbitListenerContainerFactoryConfigurer configurer,
            ConnectionFactory connectionFactory) {
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        configurer.configure(factory, connectionFactory);
        factory.setMessageConverter(messageConverter);
        return factory;
    }
    
}
--------------------------------------------------------------------------------------------------------------------------------------------------------

package com.study.soufang.rabbit.a003.springboot.rabbitmq;

import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.RabbitTemplate.ReturnCallback;

public class MyReturnCallback implements ReturnCallback {

    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
        System.out.println("Message : "+ message);
        System.out.println("replyCode : "+ replyCode);
        System.out.println("replyText : "+ replyText);
        System.out.println("exchange : "+ exchange);
        System.out.println("routingKey : "+ routingKey);
    }

}
 

------------------------------------------------------------------------------------------------------------------------------------------------------------------

package com.study.soufang.rabbit.a003.springboot.rabbitmq;

import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class TestRecv {

    @RabbitListener(queuesToDeclare=@Queue("springboot.rabbit.test.simple.queue"))
    public void processMessage(User user) throws Exception {
        System.out.println("---------"+user);
    }
    
}
 

------------------------------------------------------------------------------------------------------------------------------------------------------------------

package com.study.soufang.rabbit.a003.springboot.rabbitmq;

import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.AmqpAdmin;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.core.Queue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class TestSend {

    @Autowired
    AmqpAdmin amqpAdmin;
    @Autowired
    AmqpTemplate amqpTemplate;
    
    public void send(){
        String queueName = "springboot.rabbit.test.simple.queue";
        //注意默认队列是持久化的
        amqpAdmin.declareQueue(new Queue(queueName));
        /**
         * mandatory 默认为FALSE,如果exchange根据自身类型和消息routeKey无法找到一个符合条件的queue,会直接将消息扔掉
         * 发送过程中RabbitServer挂掉,会直接报错 Connection refused: connect
         */

        //默认消息持久化发送
        amqpTemplate.convertAndSend("",queueName, new User().setId(14).setName("中文"));

       //发送非持久化消息,RabbitServer重启后,消息丢失
        amqpTemplate.convertAndSend(queueName, new User().setId(14).setName("中文"), new MessagePostProcessor() {
            
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.NON_PERSISTENT);
                return message;
            }
        });
    }
    
}

------------------------------------------------------------------------------------------------------------------------------------------------------------------

package com.study.soufang.rabbit.a003.springboot.rabbitmq;

import java.io.Serializable;

import lombok.Data;
import lombok.experimental.Accessors;

@Data
@Accessors(chain=true)
public class User implements Serializable{

    private Integer id;
    private String name;
    
}
 

<think>好的,用户让我介绍一下Spring Boot整合RabbitMQ,我需要详细说明整合的步骤和关键点。首先,我得回忆一下Spring Boot和RabbitMQ整合的基本流程,确保没有遗漏重要步骤。 首先,应该从项目配置开始,比如添加依赖。用户可能用的是Maven,所以需要给出spring-boot-starter-amqp的依赖代码。记得检查最新的版本号,不过通常Spring Boot的parent已经管理了版本,所以可能不需要特别指定。 接下来是配置文件,application.properties或yml中的RabbitMQ连接信息。需要提到服务器地址、端口、用户名和密码。如果用户没有修改过,默认的guest/guest可能在本地有效,但生产环境肯定需要改的。 然后是核心概念的介绍,比如交换机、队列、绑定关系。这里需要简要说明Direct、Topic、Fanout等交换机类型,以及如何声明队列和绑定。用户可能需要知道如何在Spring Boot中通过配置类来声明这些Bean。 接下来是消息的生产者和消费者。生产者部分可以用RabbitTemplate来发送消息,需要示例代码展示如何convertAndSend。消费者的话,使用@RabbitListener注解监听队列,给出一个简单的例子,比如接收String类型的消息并处理。 可能还需要提到消息的序列化方式,默认是JDK序列化,但通常建议改成JSON,需要配置Jackson2JsonMessageConverter,并替换RabbitTemplate的messageConverter。这点很重要,避免用户遇到序列化问题。 还有确认机制,比如生产者的确认回调(ConfirmCallback)和返回模式(ReturnCallback),确保消息正确到达交换机和队列。这部分可能需要配置CachingConnectionFactory的相关属性,并在配置类中设置相关的回调接口。 消费者端的确认机制,手动ACK和自动ACK的区别,以及如何设置手动确认模式,并在代码中调用channel.basicAck等方法。需要提醒用户注意消息处理异常时的处理,避免消息丢失或重复消费。 最后,可以给出一些测试的方法,比如编写单元测试或者使用主程序发送消息,以及查看RabbitMQ的管理界面来验证消息是否正常流转。 需要检查是否有遗漏的步骤,比如交换机和队列的持久化设置,或者消费者的并发配置。另外,是否要提到RabbitMQ的安装和启动,或者Docker的使用?可能用户已经安装了,所以暂时可以不提,除非常见问题。 确保语言简洁,步骤清晰,每个部分都有代码示例和配置示例,方便用户跟着操作。同时提醒可能的坑,比如依赖版本冲突,配置项的正确写法,以及消息转换器的配置。最后,总结整个流程,帮助用户形成完整的认识。</think>Spring Boot整合RabbitMQ主要分为以下步骤,通过清晰的配置和注解实现消息队列的高效管理: --- ### 一、添加依赖 在`pom.xml`中引入Spring Boot对RabbitMQ的自动配置支持: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> ``` --- ### 二、配置RabbitMQ连接 在`application.properties`中配置连接信息: ```properties spring.rabbitmq.host=localhost spring.rabbitmq.port=5672 spring.rabbitmq.username=guest spring.rabbitmq.password=guest ``` --- ### 三、声明交换机、队列与绑定 通过`@Configuration`类定义消息模型: ```java @Configuration public class RabbitConfig { // 声明直连交换机 @Bean public DirectExchange directExchange() { return new DirectExchange("direct.exchange"); } // 声明队列 @Bean public Queue testQueue() { return new Queue("test.queue", true); // 持久化队列 } // 绑定队列到交换机 @Bean public Binding binding(Queue testQueue, DirectExchange directExchange) { return BindingBuilder.bind(testQueue) .to(directExchange) .with("test.routingKey"); } } ``` --- ### 四、消息生产者 注入`RabbitTemplate`发送消息: ```java @Service public class MessageProducer { @Autowired private RabbitTemplate rabbitTemplate; public void sendMessage(String message) { rabbitTemplate.convertAndSend( "direct.exchange", "test.routingKey", message ); } } ``` --- ### 五、消息消费者 使用`@RabbitListener`监听队列: ```java @Component public class MessageConsumer { @RabbitListener(queues = "test.queue") public void handleMessage(String message) { System.out.println("收到消息: " + message); } } ``` --- ### 六、高级配置 #### 1. JSON消息序列化 ```java @Configuration public class RabbitMessageConfig { @Bean public MessageConverter jsonMessageConverter() { return new Jackson2JsonMessageConverter(); } } ``` #### 2. 消息确认机制 **生产者确认**(需配置`spring.rabbitmq.publisher-confirm-type=correlated`): ```java rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> { if (!ack) System.out.println("消息未到达交换机: " + cause); }); ``` **消费者手动ACK**(配置`spring.rabbitmq.listener.simple.acknowledge-mode=manual`): ```java @RabbitListener(queues = "test.queue") public void handleMessage(Message message, Channel channel) throws IOException { try { // 处理业务逻辑 channel.basicAck(message.getMessageProperties().getDeliveryTag(), false); } catch (Exception e) { channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true); } } ``` --- ### 七、验证测试 1. **发送消息测试**: ```java @SpringBootTest class ProducerTest { @Autowired private MessageProducer producer; @Test void testSend() { producer.sendMessage("Hello RabbitMQ!"); } } ``` 2. **管理界面查看**: 访问`http://localhost:15672`(默认管理端口),查看队列消息堆积状态。 --- ### 常见问题排查 1. **连接失败**:检查RabbitMQ服务是否启动,防火墙是否开放5672端口 2. **序列化异常**:确保消息体是可序列化的POJO对象 3. **消息未消费**:检查`@RabbitListener`的队列名称是否匹配,消费者是否启动 通过以上步骤可实现Spring Boot与RabbitMQ的完整集成,建议根据实际业务需求进一步配置消息重试、死信队列等高级特性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值