RabittAdmin
RabbitAdmin类可以很好的操作RabbitMQ,在spring中直接进行注入即可
@Bean
public RabbitAdmin rabbitAdmin(ConnectionFactory connectoryFactory){
RabbitAdmin rabbitAdmin = new RabbitAdmin(connectoryFactory);
rabbitAdmin.setAutoStartup(true);
return rabbitAdmin;
}
注意 autoStartup必须设置为true,否则Spring容器不会加载RabbitAdmin类
- RabbitAdmin 底层实现就是从Spring容器中获取Exchange、Binding、Routingkry以及Queue的@Bean声明
- 然后使用RabbitTemplate的execute方法执行对应的声明、修改、删除等一系列的RabbitMQ基础功能操作;例如添加交换机,声明对列、清空对列消息等等
我们以代码的形式展示下
创建一个springboot项目,引入rabbitmq的maven依赖
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
创建RabbitMQConfig配置类
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitMQConfig {
@Bean
public ConnectionFactory connectionFactory(){
CachingConnectionFactory factory = new CachingConnectionFactory();
factory.setAddresses("127.0.0.1:5672");
factory.setUsername("guest");
factory.setPassword("guest");
factory.setVirtualHost("/");
return factory;
}
@Bean
public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory){
RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
rabbitAdmin.setAutoStartup(true);
return rabbitAdmin;
}
}
进行下测试
import org.junit.jupiter.api.Test;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class TqsApplicationTests {
@Autowired
private RabbitAdmin rabbitAdmin;
@Test
void testRabbitAdmin(){
rabbitAdmin.declareExchange(new DirectExchange("test_amqp_direct", false,false));
rabbitAdmin.declareExchange(new TopicExchange("test_amqp_topic",false,false));
rabbitAdmin.declareExchange(new FanoutExchange("test_amqp_fanout",false,false));
rabbitAdmin.declareQueue(new Queue("amqp_queue_direct", true, false, false, null));
rabbitAdmin.declareQueue(new Queue("amqp_queue_topic", true, false, false, null));
rabbitAdmin.declareQueue(new Queue("amqp_queue_fanout", true, false, false, null));
}
}
查看下我们的控制台,发现交换机和对列都已经被声明成功了
然后我们在进行下绑定
// 第一种绑定方式
rabbitAdmin.declareBinding(new Binding("amqp_queue_direct",Binding.DestinationType.QUEUE, "test_amqp_direct", "direct", null ));
再次启动测试,去控制台查看,已经绑定成功
// 第二种绑定方式
rabbitAdmin.declareBinding(BindingBuilder
.bind(new Queue("amqp_queue_direct", false))
.to(new TopicExchange("test_amqp_topic",false,false))
.with("user.#"));
// FanoutExchange不需要路由键
rabbitAdmin.declareBinding(BindingBuilder
.bind(new Queue("amqp_queue_fanout", false))
.to(new FanoutExchange("test_amqp_fanout",false,false)));
其他方法
// 清空队列消息
rabbitAdmin.purgeQueue("amqp_queue_fanout");
SpringAMQP-声明
@Bean
public Queue queue001(){
return new Queue("queue_001");
}
@Bean
public Queue queue002(){
return new Queue("queue_002");
}
@Bean
public Queue queue003(){
return new Queue("queue_003");
}
RabbitTemplate-消息模板
- 与SpringAMQP整合的时候进行发送消息的关键类
- 该类提供了丰富的发送消息方法,包括可靠性投递方法、回调监听消息接口ConfirmCallback、返回值确认接口ReturnCallback等等。同样需要进行注入到Spring容器中,然后直接使用
- 与Spring整合的时候需要实例化,但是在与Springboot整合时,在配置文件里边添加配置即可
//首先添加@Bean 实例化
@Bean
public RabbitTemplate rabbitTemplate (ConnectionFactory connectionFactory){
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
return rabbitTemplate;
}
// 进行发送测试
@Test
void testTempleate(){
MessageProperties messageProperties = new MessageProperties();
messageProperties.getHeaders().put("desc", "消息");
messageProperties.getHeaders().put("type","a001");
Message message = new Message("Hello message".getBytes(), messageProperties);
rabbitTemplate.convertAndSend("test_amqp_topic", "user.add", message, new MessagePostProcessor() {
@Override
public Message postProcessMessage(Message message) throws AmqpException {
System.out.println("--------添加额外设置----------");
message.getMessageProperties().getHeaders().put("name","wanghzhichao");
return message;
}
});
}
执行结果
其他发送方式实例:
@Test
void testTempleate01(){
MessageProperties messageProperties = new MessageProperties();
messageProperties.getHeaders().put("002", "消息002");
messageProperties.getHeaders().put("type","002");
Message message = new Message("Hello message 002".getBytes(), messageProperties);
/*方式一*/
rabbitTemplate.convertAndSend("test_amqp_topic", "user.update", "简单消息发送方式");
/*方式二*/
rabbitTemplate.send("test_amqp_topic", "user.update", message);
/*方式三*/
rabbitTemplate.convertAndSend("test_amqp_topic", "user.delete", message);
}
SimpleMessageListenerContainer-简单消息监听容器
- 这个类非常的强大,可以对它进行很多的设置,对于消费者的配置项,这个类都可以满足
- 监听队列(多个队列)自动启动、自动声明功能
- 设置事务特性,事务管理器,事务属性,事务容量(并发),是否开启事务,回滚消息等(一般不使用)
- 设置消费者数量,最大最小,批量消费
- 设置消息确认和自动确认模式,是否重回队列,异常捕获handle函数
- 设置消费者标签生成策略,是否独占模式,消费者属性
- 设置具体的监听器,消息转换器等等
注意:SimpleMessageListenerContainer可以进行动态设置,比如运行中的应用可以动态的修改其消费者数量的大小,接受消息的模式等。很多基于rabbitmq的自制定化后端管控台在进行动态设置的时候,也是根据这一特性去实现的
@Bean
public SimpleMessageListenerContainer messageListenerContainer(ConnectionFactory connectionFactory){
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
// 监听队列
container.setQueues(queue001(),queue002(),queue003());
//设置消费者数量
container.setConcurrentConsumers(1);
//设置消费者最大数量
container.setMaxConcurrentConsumers(5);
// 设置重回队列
container.setDefaultRequeueRejected(false);
// 签收模式 -自动签收
container.setAcknowledgeMode(AcknowledgeMode.AUTO);
container.setConsumerTagStrategy(new ConsumerTagStrategy() {
@Override
public String createConsumerTag(String queue) {
return queue+"_"+(new Date().getTime());
}
});
container.setMessageListener(new ChannelAwareMessageListener() {
@Override
public void onMessage(Message message, Channel channel) throws Exception {
System.out.println("message: "+new String(message.getBody()));
}
});
return container;
}
启动springboot项目,查看rabbitmq的管控台
发送消息测试
@Test
void testTempleate03(){
//将队列和交换金进行绑定
rabbitAdmin.declareBinding(BindingBuilder.bind(new Queue("queue_001"))
.to(new TopicExchange("test_amqp_topic")).with("user.#"));
rabbitAdmin.declareBinding(BindingBuilder.bind(new Queue("queue_002"))
.to(new TopicExchange("test_amqp_topic")).with("user.#"));
rabbitAdmin.declareBinding(BindingBuilder.bind(new Queue("queue_003"))
.to(new TopicExchange("test_amqp_topic")).with("user.#"));
MessageProperties messageProperties = new MessageProperties();
messageProperties.getHeaders().put("type","003");
Message message = new Message("Hello message 003".getBytes(), messageProperties);
rabbitTemplate.convertAndSend("test_amqp_topic", "user.delete", message);
}
执行测试后,查看springboot控制台,三个队列都收到了消息,并且被监听到,打印出了信息
MessageListenerAdapter-消息监听适配器
- defaultListenerMethod 默认监听方法,用于设置监听方法名称
- Delegate 委托对象:实际真实的委托对象,用于处理消息
- queueOrTagToMethodName队列标识与方法名称组成的集合
- 可以一一进行队列与方法名称的匹配
- 队列和方法名称绑定,即指定队列里消息会被绑定的方法所接受处理
MessageConverter-消息转换器
在进行发送消息的时候,正常情况下消息体为二进制的数据方式进行传输,如果希望内部帮我们进行转换,或者指定自定义的转换器,就需要用到MessageConverter
- 自定义常用转换器:MessageConverter,一般来讲都需要实现这个借口
- 重写方法:toMessage java对象转为Message fromMessage: Message对象转为java对象
1、Json转换器
2、Jackson2JsonMessageConverter:可以进行java对象的转换功能
3、DefaultJackson2JavaTypeMapper映射器:可以进行java对象的映射关系
4、自定义二进制转换器:图片、pdf、ppt、流媒体