spring专门集成了RabbmitMQ–springAMQP
学习官网https://spring.io/projects/spring-amqp#learn
第一步引入SpringAMQP相关的maven依赖
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
<version>2.3.2</version>
</dependency>
配置Rabbmit配置类
import org.springframework.amqp.core.AmqpAdmin;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* rabbmitMQ配置
*/
@Configuration
public class RabbitMQConfig {
/**
* 配置基础客户端连接工厂
* @return
*/
@Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory("localhost");
/** admin是我自己创建的账户 */
connectionFactory.setUsername("admin");
connectionFactory.setPassword("admin");
return connectionFactory;
}
/**
* 源码中会发现rabbitTemplate实现自amqpTemplate接口,使用起来并无区别
* 提供消息发布接收基本方法
* @return
*/
@Bean
public AmqpAdmin amqpAdmin() {
return new RabbitAdmin(connectionFactory());
}
@Bean
public RabbitTemplate rabbitTemplate() {
return new RabbitTemplate(connectionFactory());
}
/**
* 配置批量监听容器
* @param connectionFactory
* @return
*/
@Bean("batchQueueRabbitListenerContainerFactory")
public SimpleRabbitListenerContainerFactory batchQueueRabbitListenerContainerFactory(ConnectionFactory connectionFactory) {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
//设置批量
factory.setBatchListener(true);
//设置BatchMessageListener生效
factory.setConsumerBatchEnabled(true);
//设置监听器一次批量处理的消息数量
factory.setBatchSize(10);
//设置线程数
factory.setConcurrentConsumers(10);
//最大线程数
factory.setMaxConcurrentConsumers(10);
return factory;
}
}
1.主要配置连接工厂的ip和账户密码
2.RabbitTemplate 和AmqpAdmin用起来感觉没有区别 我选择用 RabbitTemplate (提供消息接收发送的基本方法类似于 redisTemplate)
3.配置批量监听的基本属性(批量监听的本质是springAMQP把多条消息组成一条)
接下来开始配置队列信息
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 1v1模式
*/
@Configuration
public class MqDirect {
/** 交换机名称 */
public static String Exchange_Name = "directExchange";
/** 队列名称 */
public static String Queue_Name = "myqueue";
/** 批量队列名称 */
public static String Queue_Batch_Name = "myqueueBatch";
/** 路由键 */
public static String Rout_key = "myqueue";
public static String Rout_key_Batch = "myqueueBatch";
/**
* 声明队列
* @return
*/
@Bean
Queue myQueue() {
return new Queue(Queue_Name);
}
@Bean
Queue batchQueue() {
return new Queue(Queue_Batch_Name);
}
/**
* SpringAMQP 提供了各种类型的交换机类型
* DirectExchange 1v1队列 正在使用
* FanoutExchange 广播模式
* HeadersExchange 头模式 不是很了解这个模式
* TopicExchange 模糊匹配模式
* @return
*/
@Bean
DirectExchange bindExchangeOne(){
/**
* 构造一个新的Exchange,并为其指定名称,持久性标志和自动删除标志以及*参数。
* @param name 交换的名称。
* @param durable 如果我们声明一个持久交换(交换将在服务器重启后保留),则为true
* @param autoDelete 如果服务器在不再使用该交换时应删除该交换,则为true
* @param arguments 用于声明交换的参数
*/
return new DirectExchange(Exchange_Name,false,true,null);
}
/**
* 将交换机与队列绑定同时设置路由键
* @return
*/
@Bean
Binding directBindingOne(){
return BindingBuilder.bind(myQueue()).to(bindExchangeOne()).with(Rout_key);
}
@Bean
Binding directBindingBatch(){
return BindingBuilder.bind(batchQueue()).to(bindExchangeOne()).with(Rout_key_Batch);
}
}
1.先声明队列 我这里要做个单条消息处理和批量消息处理所以做两个队列
2.声明交换机 代码上有注解 应该能看懂吧
注:rabbmit的消费模式有4个其中交换机也是对应四个的如下 不同的模式需要声明不同的交换机
DirectExchange 1v1队列 正在使用
FanoutExchange 广播模式
HeadersExchange 头模式 不是很了解这个模式
TopicExchange 模糊匹配模式
3.将交换机DirectExchange 与声明的两个对列绑定同时设置好路由键
4.Direct类型的队列配置好了 接下来测试消息发送与接收
import com.example.demo.framework.mq.MqDirect;
import com.sun.istack.internal.logging.Logger;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class MQListener {
private Logger log = Logger.getLogger(MQListener.class);
/**
* 消息一条一条打印
* @param msg
*/
@RabbitListener(queues = "myqueue")
public void direct(String msg){
log.info("myqueue监听到的消息--->"+msg);
}
/**
* 消息批量接收
* @param messages
*/
@RabbitListener(queues = "myqueueBatch",containerFactory = "batchQueueRabbitListenerContainerFactory")
public void directBatch(List<Message> messages){
log.info("myqueueBatch监听到的消息数量--->"+messages.size());
}
}
这是通过@RabbitListener实现消息异步监听
@RabbitListener 中的queues 就是队列的名字必填
@RabbitListener 中的containerFactory 指定消息批量处理方式的bean 就是那个配置类中定义的批量处理配置bean
指定containerFactory 后要把方法参数改为List<Message> messages
然后去测试类写个消息发送
import com.example.demo.framework.mq.MqDirect;
import com.example.demo.framework.mq.MqTopic;
import org.junit.jupiter.api.Test;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class RabbmitMqApplicationTests {
@Autowired
private RabbitTemplate rabbitTemplate;
/**
* 单条消息
*/
@Test
void direct(){
rabbitTemplate.convertAndSend(MqDirect.Exchange_Name,MqDirect.Rout_key,"我是消息");
}
/**
*批量消息
*/
@Test
void directBatch(){
for(int i=0;i<100;i++){
rabbitTemplate.convertAndSend(MqDirect.Exchange_Name,MqDirect.Rout_key_Batch,"我是消息");
}
}
}
查看打印结果