Springboot RabbitMq源码解析之消息发送

本文深入解析Springboot RabbitMq的源码,重点讲解了RabbitTemplate的convertAndSend过程,SimpleMessageConverter的消息转换,RabbitTemplate的send方法,消息发送确认和不可达处理。内容涵盖了从对象转换为Message,通道的创建与关闭,到消息发送确认的完整流程,以及如何处理消息不可达的情况。

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

Springboot RabbitMq源码解析之配置类

1. RabbitTemplate#convertAndSend

rabbitmq的发送可以通过AmqpTemplate接口实现,AmqpTemplate接口下重载了许多send和convertAndSend方法。send用于发送Message格式的数据,convertAndSend方法先将对象转化成Message数据后进行发送。
从前面的配置类中可以看到,默认使用的AmqpTemplate是RabbitTemplate,以RabbitTemplate#convertAndSend(String, String, Object)

@Override
public void convertAndSend(String exchange, String routingKey, final Object object, CorrelationData correlationData)
		throws AmqpException {
	send(exchange, routingKey, convertMessageIfNecessary(object), correlationData);
}

然后委托MessageConverter类将对象转化成Message数据

protected Message convertMessageIfNecessary(final Object object) {
	if (object instanceof Message) {
		return (Message) object;
	}
	return getRequiredMessageConverter().toMessage(object, new MessageProperties());
}

2. SimpleMessageConverter#createMessage

MessageConverter接口只有两个方法,分别用于将对象转换成Message和将Message还原回对象。
RabbitTemplate#messageConvert的默认值是SimpleMessageConverter,其toMessage方法继承自父类AbstractMessageConverter,具体逻辑如下,其核心逻辑在于SimpleMessageConverter#createMessage中。

@Override
public final Message toMessage(Object object, MessageProperties messageProperties)
		throws MessageConversionException {
	if (messageProperties == null) {
		messageProperties = new MessageProperties();
	}
	Message message = createMessage(object, messageProperties);
	messageProperties = message.getMessageProperties();
	if (this.createMessageIds && messageProperties.getMessageId() == null) {
		messageProperties.setMessageId(UUID.randomUUID().toString());
	}
	return message;
}
@Override
protected Message createMessage(Object object, MessageProperties messageProperties) throws MessageConversionException {
	byte[] bytes = null;
	if (object instanceof byte[]) {
		bytes = (byte[]) object;
		messageProperties.setContentType(MessageProperties.CONTENT_TYPE_BYTES);
	}
	else if (object instanceof String) {
		try {
			bytes = ((String) object).getBytes(this.defaultCharset);
		}
		catch (UnsupportedEncodingException e) {
			throw new MessageConversionException(
					"failed to convert to Message content", e);
		}
		messageProperties.setContentType(MessageProperties.CONTENT_TYPE_TEXT_PLAIN);
		messageProperties.setContentEncoding(this.defaultCharset);
	}
	else if (object instanceof Serializable) {
		try {
			bytes = SerializationUtils.serialize(object);
		}
		catch (IllegalArgumentException e) {
			throw new MessageConversionException(
					"failed to convert to serialized Message content", e);
		}
		messageProperties.setContentType(MessageProperties.CONTENT_TYPE_SERIALIZED_OBJECT);
	}
	if (bytes != null) {
		messageProperties.setContentLength(bytes.length);
		return new Message(bytes, messageProperties);
	}
	throw new IllegalArgumentException(getClass().getSimpleName()
			+ " only supports String, byte[] and Serializable payloads, received: " + object.getClass().getName());
}

SimpleMessageConverter#toMessage方法通过new Message(bytes, messageProperties)生成返回的对象。因此在转化对象时需要考虑的是如何将对象转化成字节数组以及对应的contentType。
转换成字节数组的方式根据对象类型有4种场景:
(1)字节数组:不需要转化
(2)字符串:直接使用String#getBytes
(3)可序列化对象:进行序列化
(4)其它:抛出异常

3. RabbitTemplate#send

RabbitTemplate内所有重载的send和convertAndSend方法都通过调用public void send(final String exchange, final String routingKey, final Message message, final CorrelationData correlationData) throws AmqpException来进行消息的发送,而这个方法有委托execute方法处理逻辑。


                
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值