RabbitMQ消息监听容器
你好!欢迎来到Java成长笔记,主要是用于相互交流,相互学习,也希望分享能帮到大家,如有错误之处,希望指正,谢谢!
通过配置消息监听容器,可以对队列或者多个队列进行监听,开发者可以进行相应的业务处理,实现接收和发送数据的自定义处理。
SimpleMessageListenerContainer
1、SimpleMessageListenerContainer进行很多设置,消费者的配置项进行设置,可以满足监听队列(多个队列)、自动启动、自动声明功能。
2、简单消息监听容器
1)设置事务特性、事务管理器、事务属性、事务容量(并发)、是否开启事务、回滚消息等。
2)设置消费者数量、最小最大数量、批量消费。
3、设置消息确认和自动确认模式、是否重回队列、异常捕获handler函数。
4、设置消费者标签生成策略、是否独占模式、消费者属性等。
5、设置具体的监听器、消息转換器等等。
6、SimpleMessageListenerContainer可以进行动态设置,比如在运行中的应用可以动态的修改其消费者数量的大小、接收消息的模式等。
基础设置加载,代码展示如下:
/**
* 基础设置加载
*/
public void init (final SimpleMessageListenerContainer container) {
// 同时监听多个队列
container.setQueues(queue001(), queue002(), queue003(), queue_image(), queue_pdf());
// 设置当前的消费者数量和最大消费者数量
container.setConcurrentConsumers(1);
container.setMaxConcurrentConsumers(5);
// 设置是否重回队列
container.setDefaultRequeueRejected(false);
// 设置是否自动签收
container.setAcknowledgeMode(AcknowledgeMode.AUTO);
// 设置是否监听
container.setExposeListenerChannel(true);
// 设置消费端标签策略
container.setConsumerTagStrategy(new ConsumerTagStrategy() {
@Override
public String createConsumerTag(String s) {
return s + "_" + UUID.randomUUID().toString();
}
});
}
消息监听端配置,代码展示如下:
@Bean
public SimpleMessageListenerContainer messageContainer(ConnectionFactory connectionFactory) {
final SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
this.init(container);
// 设置消息监听
container.setMessageListener(new ChannelAwareMessageListener() {
@Override
public void onMessage(Message message, Channel channel) throws Exception {
final String msg = new String(message.getBody());
log.error(" 消费者 --->>> " + msg);
}
});
return container;
}
MessageListenerAdapter
适配器方法(一)
指定消息转换器,将字节数组转换为String
代码展示如下:
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.support.converter.MessageConversionException;
import org.springframework.amqp.support.converter.MessageConverter;
import java.util.Optional;
@Slf4j
public class TextMessageConverter implements MessageConverter {
/**
* @Description: Object转为Message
*/
@Override
public Message toMessage(Object object, MessageProperties messageProperties) throws MessageConversionException {
return new Message(object.toString().getBytes(), messageProperties);
}
/**
* @Description: Message转为Java对象
*/
@Override
public Object fromMessage(Message message) throws MessageConversionException {
final String contentType = message.getMessageProperties().getContentType();
Optional.ofNullable(contentType)
.filter(StringUtils::isNotBlank)
.filter(x->contentType.contains("test"))
.map(z->{
return new String(message.getBody());
});
return message.getBody();
}
}
// 监听类设置配置
@Bean
public SimpleMessageListenerContainer messageContainer(ConnectionFactory connectionFactory) {
final SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
this.init(container);
final MessageListenerAdapter adapter = new MessageListenerAdapter(new MessageDelegate());
// 方法委托 自定义方法
adapter.setDefaultListenerMethod("consumeMessage");
adapter.setMessageConverter(new TextMessageConverter());
container.setMessageListener(adapter);
return container;
}
public void consumeMessage(byte[] messageBody) {
log.error("字节数组方法,消息内容:{}", new String(messageBody));
}
// 测试类
@Test
public void testSendMessage4Text() throws Exception {
//1 创建消息
MessageProperties messageProperties = new MessageProperties();
messageProperties.setContentType("text/plain");
Message message = new Message("TextMessageConverter配置mq消息Message".getBytes(), messageProperties);
// 发送消息
rabbitTemplate.send("topic001", "spring.abc", message);
rabbitTemplate.send("topic002", "rabbit.abc", message);
}
如果不配置setDefaultListenerMethod方法,下图为监听类默认方法
适配器方法(二)
将队列名称和消息转换方法进行一对一匹配
代码展示如下: