springboot整合rabbitmq和发布订阅模型基本使用
一 整合rabbitmq
1 添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
<version>${springboot.version}</version>
</dependency>
2 配置文件指定地址
spring.rabbitmq.host=10.3.64.109
spring.rabbitmq.port=5673
spring.rabbitmq.username=hd
spring.rabbitmq.password=Hd@001
spring.rabbitmq.virtualHost=/hdHost
spring.rabbitmq.listener.concurrency=5
3 发送端声明队列
程序启动的话 可以自动创建lkfxQueue队列
public Queue lkfxQueue() {
return new Queue(QueueName.HD_HDHZSHFX_QUEUE);
}
4 发送端发送简单队列模型
@Scheduled(cron = "0 0/5 * * * ?")
public void sendHd() {
String json = “字符串”;
rabbitTemplate.convertAndSend(QueueName.HD_HDHZSHFX_QUEUE, json);
}
5 接收端代码
使用@RabbitListener监听发送端指定的队列
@RabbitListener(queues = QueueName.HD_HDHZSHFX_QUEUE)
@RabbitHandler
public void saveHdShfx(String str) {
System.out.println(str);
}
二 发布订阅模型
根据交换机的类型分为3种: 广播(Fanout Exchange) 路由(Direct Exchage) 主题(Topic Exchange)
一 Fanout Exchange
往交换机中发送消息 – 交换机绑定的队列都可以收到消息
1 发送者端代码
声明队列和交换机 -- spring启动自动创建队列和交换机
@Bean
public FanoutExchange fanoutExchange() {
return new FanoutExchange("fanout.queue1");
}
//绑定第一个队列
@Bean
public Binding bindingQueue1() {
return BindingBuilder.bind(QueueName.HD_HDHZSHFX_QUEUE).to(fanoutExchange());
}
//绑定第二个队列
@Bean
public Binding bindingQueue1() {
return BindingBuilder.bind(QueueName.SECOND).to(fanoutExchange());
}
2 发送到交换机
@Scheduled(cron = "0 0/5 * * * ?")
public void sendHd1() {
String exchangeName = "itcast.fanout";
String message = "hello";
//routingkey为空
rabbitmqTemplate.convertAndSend(exchangeName,"",message);
}
3 接收端 监听2个队列
@RabbitListener(queues = QueueName.HD_HDHZSHFX_QUEUE)
@RabbitHandler
public void saveHdShfx(String str) {
System.out.println(str);
}
@RabbitListener(queues = QueueName.SECOND)
@RabbitHandler
public void saveHdShfx(String str) {
System.out.println(str);
}
二 directExchage
声明队列和交换机 接收端
同样可以使用@Bean方式声明,还可以使用@RabbitListener注解声明 队列和交换机
队列里面可以使用动态的#或者$符号 来读取bean或者配置文件中的信息
//声明的第一个队列根据自己的路由规则绑定itcast.direct交换机
@RabbitListener(bindings = @QueueBinding(
value = @Queue(value = "#{queue1.name}",autoDelete = "false",durable = "true"),
exchange = @Exchange(value = "itcast.direct",type = ExchangeTypes.DIRECT),
key = "red"
))
public void saveMessage2(String str) throws ParseException {
}
//声明的第2个队列根据自己的路由规则绑定itcast.direct交换机
@RabbitListener(bindings = @QueueBinding(
value = @Queue(value = "#{queue1.name}",autoDelete = "false",durable = "true"),
exchange = @Exchange(value = "itcast.direct",type = ExchangeTypes.DIRECT),
key = "blue"
))
public void saveMessage2(String str) throws ParseException {
}
发送端代码编写
@Scheduled(cron = "0 0/5 * * * ?")
public void sendHd1() {
String exchangeName = "itcast.fanout";
String message = "hello";
//routingkey为指定的路由键
rabbitmqTemplate.convertAndSend(exchangeName,"blue",message);
}
三 TopicExchage
和directTopic不同的是,交换机绑定队列的routingkey必须以.分隔
声明队列和交换机 接收端
@Component
public class DirectConfig {
@Value("${sync.topic.queueName}")
private String queueName;
//声明动态队列
@Bean(name = "dicQueue")
public Queue queue() {
return new Queue(queueName);
}
//声明topic交换机
@Bean(name = "dicTopicExchange")
public TopicExchange topicExchange() {
return new TopicExchange("topic.dic");
}
//动态队列以dic.*的形式绑定到topic交换机上
// *表示1个单词 # 表示0或者多个单词
@Bean(name = "dicBinding")
public Binding binding(@Qualifier("dicTopicExchange") TopicExchange exchange, @Qualifier("dicQueue") Queue queue) {
return BindingBuilder.bind(queue).to(exchange).with("dic.*");
}
}
发送端
@Scheduled(cron = "0 0 6,18 * * ?")
public void sendMessage() {
//发送到topic交换机中 routingkey使用dic.lj 可发送到对应规则的队列中
// 以dic.*绑定topic的队列 都可以接收到消息
String str = "sss";
rabbitTemplate.convertAndSend("topic.dic","dic.lj",str);
}