- 前言
上一篇博客整理了一些RabbitMQ的一些高级特性,像confirm消息确认机制,消费端限流等等。今天这篇博客主要整理下Spring AMQP与RabbitMQ的整合,主要是一些常用组件的使用。整理的比较简单,但是代码都是自己本地运行成功的,如果有什么问题,希望可以及时指出交流。
- Spring AMQP用户管理组件——RabbitAdmin
RabbitAdmin封装了对RabbitMQ的一些操作,比如声明交换机,声明队列,绑定交换机和队列等等。
- RabbitAdmin需要设置setAutoStartup参数为true,这样在启动spring 的时候才会去加载
- RabbitAdmin底层是通过RabbitTemplate去完成声明,修改,删除的一系列RabbitMQ操作
代码示例
这边通过JavaConfig的方式来装配Bean。RabbitAdmin需要一个ConnectionFactory对象,我们将ConnectionFactory注入。然后注入RabbitAdmin对象。
/**
* SpringAMQP RabbitAdmin配置类
* @author Y
* @date 2020年2月4日
*/
@Configuration
public class RabbitConfig {
@Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setAddresses("192.168.159.128:5672");
connectionFactory.setUsername("guest");
connectionFactory.setPassword("guest");
connectionFactory.setVirtualHost("/");
return connectionFactory;
}
@Bean
public RabbitAdmin rabbitAdmin() {
RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory());
rabbitAdmin.setAutoStartup(true);
return rabbitAdmin;
}
}
之后我们就可以通过RabbitAdmin来进行一系列的RabbitMQ操作。这边我测试了声明交换机和队列,以及交换机和队列的绑定操作。
/**
* RabbitMQ测试类
* @author Y
* @date 2020年2月11日
*/
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {RabbitConfig.class})
public class RabbitTest {
@Autowired
private RabbitAdmin rabbitAdmin;
@Test
public void test01() {
//声明交换机
rabbitAdmin.declareExchange(new DirectExchange("test.direct.exchange", false, false));
rabbitAdmin.declareExchange(new TopicExchange("test.topic.exchange", false, false));
//声明队列
rabbitAdmin.declareQueue(new Queue("test.direct.queue", false));
rabbitAdmin.declareQueue(new Queue("test.topic.queue", false));
//绑定交换机和队列
rabbitAdmin.declareBinding(new Binding("test.direct.queue", Binding.DestinationType.QUEUE,
"test.direct.exchange", "test", new HashMap<>()));
rabbitAdmin.declareBinding(BindingBuilder.bind(new Queue("test.topic.queue", false)).
to(new TopicExchange("test.topic.exchange", false, true)).with("#"));
}
}
执行测试方法,通过RabbitMQ管控平台,可以看到声明的交换机和队列,以及交换机和队列的绑定关系。
- Spring AMQP消息模块组件——RabbitTemplate
RabbitTemplate是Spring AMQP与RabbitMQ整合的发送消息的一个很关键的类,它提供了很多有效的方法,像回调监听ConfirmCallback,返回监听ReturnCallback等等。
同样,我们也通过@Bean注解,将RabbitTemplate注入到spring容器中,RabbitTemplate也需要一个ConnectionFactory对象。
@Bean
public RabbitTemplate rabbitTemplate() {
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory());
rabbitTemplate.setConfirmCallback(new MyConfirmCallback());//设置确认消息的回调函数
return rabbitTemplate;
}
使用rabbitTemplate进行消息的发送操作,convertAndSend方法会进行一次转换,将对象转换成 AMQP Message的格式。
@Autowired
private RabbitTemplate rabbitTemplate;
@Test
public void test02() {
rabbitTemplate.convertAndSend("test.topic.exchange", "test", "卧槽无情");
rabbitTemplate.convertAndSend("test.topic.exchange", "haha", "卧槽 哈哈", new MessagePostProcessor() {
//自定义设置消息的一些属性
@Override
public Message postProcessMessage(Message message) throws AmqpException {
message.getMessageProperties().getHeaders().put("name", "ahao");
return message;
}
});
}
执行测试方法,查看RabbitMQ管控平台,可以看到发送的两条等待消费的消息。
- Spring AMQP消息容器——SimpleMessageListenerContainer
SimpleMessageListenerContainer是一个很强大的类,他是一个消息监听的容器,它可以监听指定的多个队列,设置消息确认和自动确认的策略,设置具体的消息转换器以及监听器等等。这边只对最简单的用法做一个总结。
我们通过@Bean注解将SimpleMessageListenerContainer对象注入到spring容器中,SimpleMessageListenerContainer也需要指定一个ConnectionFactory对象。这边指定监听的队列是之前创建的test.topic.queue队列。
/**
* 消息监听容器
* @return
*/
@Bean
public SimpleMessageListenerContainer simpleMessageListenerContainer() {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory());
//手动应答
container.setAcknowledgeMode(AcknowledgeMode.AUTO);
//监听的队列
container.setQueueNames("test.topic.queue");
//消费者数量
container.setConcurrentConsumers(1);
//最大消费者数量
container.setMaxConcurrentConsumers(5);
//设置ConsumerTag命名的规则
container.setConsumerTagStrategy(new ConsumerTagStrategy() {
@Override
public String createConsumerTag(String queue) {
return queue+"_"+CommUtils.uuid();
}
});
//设置消息监听
container.setMessageListener(new ChannelAwareMessageListener() {
@Override
public void onMessage(Message message, Channel channel) throws Exception {
String msg = new String(message.getBody(),"UTF-8");
System.out.println("------------消费者---------- "+msg);
}
});
return container;
}
这边直接运行测试方法,会启动消息容器。可以看到之前发送的两条消息已经被消费了。