-
效果
-
第一步:引入pom依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
</dependencies>
```
- 第二步
编写配置类
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class QueueConfiguration {
/**
* 声明队列
* @return
*/
@Bean//生成对应message的队列
public Queue queueMessage() {
return new Queue("ccc_qqq_ggg",true,false,false);
}
//特别要注意,导Queue包的,要导入spring的mq核心包
import org.springframework.amqp.core.Queue;
- 第三步,配置rabbitmq地址
rabbitmq:
# addresses: localhost:5672
host: localhost
port: 5672
username: guest
password: guest
virtual-host: /
listener:
simple:
retry:
enabled: true
max-attempts: 2
initial-interval: 2000
# publisher-confirm-type: simple
# publisher-returns: true
- 第四步,编写消息生产者类
import com.hc.service.HelloService;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class HelloServiceImpl implements HelloService {
@Autowired
RabbitTemplate rabbitTemplate;
@Override
public void myPoducer() {
System.out.println("service");
rabbitTemplate.convertAndSend("ccc_qqq_ggg","ssffgghh");
System.out.println("end");
}
- 操作完上述步骤,就看到效果一了。
疑问?
为什么,在rabbitTemplate.convertAndSend()的时候已经指定队列名字“ccc_qqq_ggg”了,还要在配置类中new Queue()也指定队列名?
实验,将配置类注释
-
第一步操作,注释掉配置类
-
第二步,继续发送一次,看效果,效果如下,第二条消息放入队列成功
所以,疑问解决,rabbitTemplate.convertAndSend()指定队列名,就不用在配置类中再次指定了。
疑问二?上述操作的前提条件是,在rabbitmq系统中已经手动创建好交换机“c_all_thing”和队列“ccc_qqq_ggg”,并且手动绑定了。
详细操作见另一篇记录
https://blog.youkuaiyun.com/qq_28967139/article/details/119216362
所以
假如,在mq管理系统中,不手动创建交换机和队列,看能否成功?
- 第一步,对消息放入一个不存在的队列,例如“aa_bb_cc_dd”
@Autowired
RabbitTemplate rabbitTemplate;
@Override
public void myPoducer() {
System.out.println("service");
rabbitTemplate.convertAndSend("aa_bb_cc_dd","ssffgghh");
System.out.println("end");
- 效果
第二种实验,在rabbitmq配置文件中,创建队列名,创建交换机,然后在代码中将两者绑定。然后再次发送到该队列中,看是否能成功。
@Configuration
public class QueueConfiguration {
/**
* 声明队列
* @return
*/
@Bean//生成对应message的队列
public Queue queueMessage() {
return new Queue("aa_bb_cc_dd",true,false,false);
}
/**
* 声明交换机
*/
@Bean
public FanoutExchange exchange(){
return new FanoutExchange("t_h_i_s",true,false);
}
/**
* 声明绑定关系
* @return
*/
@Bean
public Binding queueBinding(Queue queue, FanoutExchange exchange){
return BindingBuilder.bind(queue).to(exchange);
}
}
//上面用代码,创建了队列名,交换机名,并将交换机和队列绑定。
- 发送代码
@Autowired
RabbitTemplate rabbitTemplate;
@Override
public void myPoducer() {
System.out.println("service");
rabbitTemplate.convertAndSend("aa_bb_cc_dd","ssffgghh");
System.out.println("end");
}
// 发送到队列“”aa_bb_cc_dd“”
- 效果
结论:
1、如果在mq管理系统中,手动创建交换机和队列,并且手动绑定了。在代码中就不需要创建交换机和队列了(也就是不需要mq配置类)。直接convertAndSend到已手动创建好的队列中即可。
2、如果不想在mq管理系统中手动创建,可以在代码中,创建mq的配置类(@@Configuration),在类中,创建队列new Queue,创建交换机new FanoutExchange,将两者绑定BindingBuilder.bind(queue).to(exchange)。
然后convertAndSend发送到这个队列即可。到时候在mq管理系统中查看,会自动创建好。
疑问三?如果手动也创建了,代码中在配置文件中也创建了,会怎么样?
会报一个错误:“channel error”。原因就是冲突了
- 由于RabbitMQ中已经存在相同名字的交换机(exchange),在创建交换机时更换另一个名字即可,或者在RabbitMQ管理界面将当前同名交换机删除就可以重新创建交换机