首先简单说一下rabbitmq吧,在rabbitmq里,publisher发布的消息会先进exchange里,然后有很多队列绑定到exchange上,exchange根据消息自身携带的路有键判断是把信息交给哪个队列,然后消费者就能连接上队列去消费消息了。
exchange分发消息时根据类型不同分发策略是不同的,常见的主要有direct、fanout、topic。
direct需要路由键与队列名完全一致,比如路由键是person,那么只会发送信息到名为person的队列中;fanout交换器会把消息给旗下绑定的每个队列都发一份;topic会对路由键做模糊匹配,然后分发,那么就涉及一些通配符,比如#(匹配多个单词)和*(匹配一个单词),比如有个队列绑定的路有键是person.#,那么只要路有键以person开头的消息都会进这个队列。
接下来我们进行一个最简单的例子,首先在localhost:15672里创建一个类型为direct的名为exchange.direct的exchange,然后创建一个名为sunsy.msg路有键为sunsy.msg的队列,绑定到exchange.direct上,然后写个测试类测一下效果,代码如下:
package com.sunsy.rabbitmq.demo;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTests {
@Autowired
RabbitTemplate rabbitTemplate;
//点对点
@Test
public void publish() {
Map<String, Object> map = new HashMap<>();
map.put("msg", "hello world");
rabbitTemplate.convertAndSend("exchange.direct", "sunsy.msg", map);
}
@Test
public void receive() {
Object o = rabbitTemplate.receiveAndConvert("sunsy.msg");
System.out.println(o.getClass());
System.out.println(o);
}
}
run with test publish之后我们去localhost:15672上查看,发现消息已经发送到sunsy.msg队列上了,然后run with test receive可以打印出收到的信息。
然后我们来看一下RabbitListener的使用,首先在主启动类上配置@EnableRabbit注解,然后我们写一个service类,如下:
package com.sunsy.rabbitmq.demo;
import java.util.Map;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;
@Service
public class MainService {
@RabbitListener(queues="sunsy.msg")
public void receive(Map<String, Object> map) {
System.out.println("msg:" + map);
}
}
我们启动服务,发现每运行一次test的publis测试,控制台都会自动打印出我们发送的消息。
这时候我们发现一个问题,我们的队列、exchange等现在都是手动创建的,那么怎么用代码生成呢?如下:
@Autowired
private AmqpAdmin amqpAdmin;
@Test
public void createExchange() {
amqpAdmin.declareExchange(new DirectExchange("sunsy.Exchange"));
amqpAdmin.declareQueue(new Queue("sunsy.testQueue"));
amqpAdmin.declareBinding(new Binding("sunsy.testQueue", Binding.DestinationType.QUEUE, "sunsy.Exchange", "sunsy.test", null));
}