1:RabbitMq基本的使用
public static void main(String[] args) throws Exception{
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("localhost");
try(Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel()) {
//创建交换机
channel.exchangeDeclare(
"exchange-test",
BuiltinExchangeType.TOPIC,
true,
false,
null
);
//创建队列
channel.queueDeclare(
"queue-text",
true,
false,
false,
null
);
//绑定
channel.queueBind("queue-text","exchange-test","test.key");
String message = "hello";
//发送消息
channel.basicPublish("exchange-test","test.key",null,message.getBytes());
}
}
2:RabbitMq整合SpringBoot
-
但是自从有了SpringBoot之后,我们当然不会再像上面这样编写代码了,我们声明队列,交换机会使用一个配置类
@Bean public Exchange exchange1() { return new DirectExchange("exchange.order.restaurant",true,false,null); } @Bean public Queue queue1() { return new Queue("queue.order",true,false,false,args); } @Bean public Binding binding1() { return new Binding( "queue.order", Binding.DestinationType.QUEUE, "exchange.order.restaurant", "key.order", null); } -
配置RabbitAdmin,ConnectionFactory,RabbitTemplate
@Bean public ConnectionFactory connectionFactory() { CachingConnectionFactory connectionFactory = new CachingConnectionFactory(); connectionFactory.setHost("localhost"); connectionFactory.setPort(5672); connectionFactory.setUsername("guest"); connectionFactory.setPassword("guest"); /** * 需要开启消息确认和返回机制 */ connectionFactory.setPublisherConfirmType(CachingConnectionFactory.ConfirmType.CORRELATED); connectionFactory.setPublisherReturns(true); return connectionFactory; } @Bean public RabbitAdmin rabbitAdmin(@Autowired ConnectionFactory connectionFactory) { RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory); rabbitAdmin.setAutoStartup(true); return rabbitAdmin; } @Bean public RabbitTemplate rabbitTemplate(@Autowired ConnectionFactory connectionFactory) { RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory); rabbitTemplate.setMandatory(true); rabbitTemplate.setReturnsCallback((returnedMessage)->{ log.info("消息:{}",returnedMessage); }); rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() { @Override public void confirm(CorrelationData correlationData, boolean ack, String s) {; log.info("correlationData:{},ack:{},s:{}",correlationData,ack,s); } }); return rabbitTemplate; } -
配置消息监听,
@Bean public SimpleMessageListenerContainer listenerContainer(ConnectionFactory connectionFactory) { SimpleMessageListenerContainer messageListenerContainer = new SimpleMessageListenerContainer(connectionFactory); messageListenerContainer.setQueueNames("queue.order"); //设置并发消费者数量 messageListenerContainer.setConcurrentConsumers(3); messageListenerContainer.setMaxConcurrentConsumers(5); //设置消息自动确认机制 messageListenerContainer.setAcknowledgeMode(AcknowledgeMode.AUTO); messageListenerContainer.setMessageListener(new MessageListener() { @Override public void onMessage(Message message) { log.info("消息内容为:{}",new String(message.getBody())); } }); //消费端限流 messageListenerContainer.setPrefetchCount(1); return messageListenerContainer; } -
发送消息
rabbitTemplate.send("exchange.order.restaurant","key.order",message,correlationData); -
结果测试
3:为什么要写第二步呢??
- 我们除了使用 @RabbitListener来监听消息,其实也可以使用 SimpleMessageListenerContainer 来监听消息
- 为什么SimpleMessageListenerContainer可以监听消息
- 因为SimpleMessageListenerContainer有一个setMessageListener方法,需要传递一个MessageListener对象
- MessageListener是一个侦听器接口,用于接收Amqp消息的异步传递,简单来说就是可以接受Amqp中的消息
4:那么现在对于 @RabbitListener 的实现你有没有一个大胆的想法呢??
- 我们大胆猜测一下,@RabbitListener 这个注解的底层是不是也是使用 SimpleMessageListenerContainer这个监听容器来监听消息的呢
5:文末
- 这里主要是解释一下如何使用 SimpleMessageListenerContainer 来监听消息,这对于后面分析 @RabbitListener 这个注解有很大帮助