1、SpringAMQP用户管理组件RabbitAdmin。

  RabbitAdmin类可以很好的操作RabbitMQ,在Spring中直接进行注入即可。注意,autoStartup必须设置为true,否则Spring容器不会加载RabbitAdmin类。RabbitAdmin底层实现就是从Spring容器中获取Exchange交换机、Binding绑定、RoutingKey路由键以及Queue队列的@Bean声明。

  然后使用RabbitTemplate的execute方法执行对应的声明、修改、删除等一系列RabbitMQ基础功能操作。例如,添加一个交换机、删除一个绑定、清空一个队列里面的消息等待操作。

2、由于使用的maven工程配合了Springboot整合Spring与RabbitMQ的知识。所以先引入依赖包,如下所示:

 <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2..RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.bie</groupId>
<artifactId>rabbitmq-spring</artifactId>
<version>0.0.-SNAPSHOT</version>
<name>rabbitmq-spring</name>
<description>Demo project for Spring Boot</description> <properties>
<project.build.sourceEncoding>UTF-</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-
</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<maven-jar-plugin.version>3.1.</maven-jar-plugin.version>
</properties> <dependencies>
<!-- Spring与RabbitMQ整合的包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit-test</artifactId>
<scope>test</scope>
</dependency>
<!-- RabbitMQ基础核心包 -->
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
</dependency>
</dependencies> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build> </project>

由于使用的是Springboot项目配合RabbitMQ来做的,所以配置文件这里使用了注解来替换,所以启动的时候,加载如下所示配置类,如下所示:

 package com.bie;

 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.ComponentScan;
import org.springframework.context.annotation.Configuration; /**
*
* @author biehl
*
*/
@Configuration
@ComponentScan(basePackages = "com.bie")
public class RabbitMQConfig { /**
* 将ConnectionFactory注入到bean容器中
*
* @return
*/
@Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setAddresses("192.168.110.133:5672");
connectionFactory.setUsername("guest");
connectionFactory.setPassword("guest");
connectionFactory.setVirtualHost("/");
return connectionFactory;
} /**
* 参数依赖上面注入的ConnectionFactory类,所以保持参数名称和注入的ConnectionFactory一致
*
* @param connectionFactory
* @return
*/
@Bean
public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
// 注意:autoStartup必须设置为true,否则Spring容器不会加载RabbitAdmin类。
rabbitAdmin.setAutoStartup(true);
return rabbitAdmin;
} }

项目主启动类,如下所示:

 package com.bie;

 import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication
public class RabbitmqSpringApplication { public static void main(String[] args) {
SpringApplication.run(RabbitmqSpringApplication.class, args);
} }

下面演示一下,Spring整合RabbitMQ,创建交换机,创建队列,将交换机和队列绑定的示例代码,如下所示:

 package com.bie;

 import java.util.HashMap;

 import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
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;
import org.springframework.test.context.junit4.SpringRunner; /**
*
* @author biehl
*
*/
@SpringBootTest
@RunWith(SpringRunner.class)
public class RabbitmqSpringApplicationTests { @Autowired
private RabbitAdmin rabbitAdmin; @Test
public void rabbitmqAdmin() {
// 参数1交换机名称, 参数1是否持久化durable, 参数3是否自动删除 autoDelete
// 创建direct类型的交换机
DirectExchange directExchange = new DirectExchange("test.directExchange", false, false);
rabbitAdmin.declareExchange(directExchange); // 创建topic类型的交换机
TopicExchange topicExchange = new TopicExchange("test.topicExchange", false, false);
rabbitAdmin.declareExchange(topicExchange); // 创建fanout类型的交换机
FanoutExchange fanoutExchange = new FanoutExchange("test.fanoutExchange", false, false);
rabbitAdmin.declareExchange(fanoutExchange); // 创建direct类型的队列
Queue directQueue = new Queue("test.direct.queue", false);
rabbitAdmin.declareQueue(directQueue); // 创建topic类型的交队列
Queue topicQueue = new Queue("test.topic.queue", false);
rabbitAdmin.declareQueue(topicQueue); // 创建fanout类型的队列
Queue fanoutQueue = new Queue("test.fanout.queue", false);
rabbitAdmin.declareQueue(fanoutQueue); // 声明绑定
// 参数1 String destination,可以认为是具体的队列。
// 参数2 DestinationType destinationType,绑定的类型。
// 参数3 String exchange,交换机的名称。
// 参数4 String routingKey,路由键的名称。
// 参数5 Map<String, Object> arguments可以传入的参数。
// 将test.directExchange交换机和test.direct.queue队列进行绑定
rabbitAdmin.declareBinding(new Binding("test.direct.queue", Binding.DestinationType.QUEUE,
"test.directExchange", "direct", new HashMap<>())); // 将test.topicExchange交换机和test.topic.queue队列进行绑定
// rabbitAdmin.declareBinding(new Binding("test.topic.queue",
// Binding.DestinationType.QUEUE, "test.topicExchange",
// "topic", new HashMap<>()));
rabbitAdmin.declareBinding(BindingBuilder.bind(new Queue("test.topic.queue", false)) // 直接创建队列
.to(new TopicExchange("test.topicExchange", false, false)) // 直接创建交换机 建立关联关系
.with("user.#")); // 指定路由Key // 将test.fanoutExchange交换机和test.fanout.queue队列进行绑定
// rabbitAdmin.declareBinding(new Binding("test.fanout.queue",
// Binding.DestinationType.QUEUE,
// "test.fanoutExchange", "", new HashMap<>())); rabbitAdmin.declareBinding(BindingBuilder.bind(new Queue("test.fanout.queue", false)) // 直接创建队列
.to(new FanoutExchange("test.fanoutExchange", false, false))); // 直接创建交换机 建立关联关系 // 清空队列数据
rabbitAdmin.purgeQueue("test.direct.queue", false);
rabbitAdmin.purgeQueue("test.topic.queue", false);
rabbitAdmin.purgeQueue("test.fanout.queue", false);
} }

执行代码,完毕,可以在RabbitMQ的管控台查询效果,效果如下所示:

3、使用SpringAMQP去声明,就需要使用SpringAMQP的如下模式,即声明@Bean方式。SpringAMQP-RabbitMQ声明式配置使用。可以在初始化加载配置文件中创建好交换机,队列,以及交换机和队列的绑定关系,启动项目即可将交换机,队列,以及交换机和队列的绑定创建,如下所示:

 package com.bie;

 import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
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.ComponentScan;
import org.springframework.context.annotation.Configuration; /**
*
* @author biehl
*
*/
@Configuration
@ComponentScan(basePackages = "com.bie")
public class RabbitMQConfig { /**
* 将ConnectionFactory注入到bean容器中
*
* @return
*/
@Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setAddresses("192.168.110.133:5672");
connectionFactory.setUsername("guest");
connectionFactory.setPassword("guest");
connectionFactory.setVirtualHost("/");
return connectionFactory;
} /**
* 参数依赖上面注入的ConnectionFactory类,所以保持参数名称和注入的ConnectionFactory一致
*
* @param connectionFactory
* @return
*/
@Bean
public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
// 注意:autoStartup必须设置为true,否则Spring容器不会加载RabbitAdmin类。
rabbitAdmin.setAutoStartup(true);
return rabbitAdmin;
} // 使用SpringAMQP去声明,就需要使用SpringAMQP的如下模式,即声明@Bean方式。
// SpringAMQP-RabbitMQ声明式配置使用 /**
* 针对消费者配置:
*
* 1. 设置交换机类型。
*
* 2. 将队列绑定到交换机。
*
* FanoutExchange: 将消息分发到所有的绑定队列,无routingkey的概念。
*
* HeadersExchange :通过添加属性key-value匹配。
*
* DirectExchange:按照routingkey分发到指定队列。
*
* TopicExchange:多关键字匹配。
*/
@Bean
public TopicExchange topicExchange001() {
return new TopicExchange("topic001", true, false);
} @Bean
public Queue queue001() {
return new Queue("queue001", true);// 队列持久化
} @Bean
public Binding bingding001() {
return BindingBuilder.bind(queue001()).to(topicExchange001()).with("spring.*");
} // 第二个交换机通过路由键绑定到队列上面。
@Bean
public TopicExchange topicExchange002() {
return new TopicExchange("topic002", true, false);
} @Bean
public Queue queue002() {
return new Queue("queue002", true);// 队列持久化
} @Bean
public Binding bingding002() {
return BindingBuilder.bind(queue002()).to(topicExchange002()).with("rabbit.*");
} // 第三个,队列通过路由键绑定到第一个队列上面,即第一个交换机绑定了两个队列。
@Bean
public Queue queue003() {
return new Queue("queue003", true);// 队列持久化
} @Bean
public Binding bingding003() {
return BindingBuilder.bind(queue003()).to(topicExchange001()).with("mq.*");
} @Bean
public Queue queue_image() {
return new Queue("image_queue", true); // 队列持久
} @Bean
public Queue queue_pdf() {
return new Queue("pdf_queue", true); // 队列持久
} }

4、RabbitTemplate,即消息模板,我们在与SpringAMQP整合的时候进行发送消息的关键类。该类提供了丰富的发送消息方法,包括可靠性投递消息方法,回调监听消息接口ConfirmCallback,返回值确认ReturnCallBack等等。同样我们需要进行注入到Spring容器中,然后直接使用。在与Spring整合的时候需要实例化,但是在与SpringBoot整合的时候,在配置文件里面添加配置即可。

 package com.bie;

 import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
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.ComponentScan;
import org.springframework.context.annotation.Configuration; /**
*
* @author biehl
*
*/
@Configuration
@ComponentScan(basePackages = "com.bie")
public class RabbitMQConfig { /**
* 将ConnectionFactory注入到bean容器中
*
* @return
*/
@Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setAddresses("192.168.110.133:5672");
connectionFactory.setUsername("guest");
connectionFactory.setPassword("guest");
connectionFactory.setVirtualHost("/");
return connectionFactory;
} /**
* 参数依赖上面注入的ConnectionFactory类,所以保持参数名称和注入的ConnectionFactory一致
*
* @param connectionFactory
* @return
*/
@Bean
public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
// 注意:autoStartup必须设置为true,否则Spring容器不会加载RabbitAdmin类。
rabbitAdmin.setAutoStartup(true);
return rabbitAdmin;
} // 使用SpringAMQP去声明,就需要使用SpringAMQP的如下模式,即声明@Bean方式。
// SpringAMQP-RabbitMQ声明式配置使用 /**
* 针对消费者配置:
*
* 1. 设置交换机类型。
*
* 2. 将队列绑定到交换机。
*
* FanoutExchange: 将消息分发到所有的绑定队列,无routingkey的概念。
*
* HeadersExchange :通过添加属性key-value匹配。
*
* DirectExchange:按照routingkey分发到指定队列。
*
* TopicExchange:多关键字匹配。
*/
@Bean
public TopicExchange topicExchange001() {
return new TopicExchange("topic001", true, false);
} @Bean
public Queue queue001() {
return new Queue("queue001", true);// 队列持久化
} @Bean
public Binding bingding001() {
return BindingBuilder.bind(queue001()).to(topicExchange001()).with("spring.*");
} // 第二个交换机通过路由键绑定到队列上面。
@Bean
public TopicExchange topicExchange002() {
return new TopicExchange("topic002", true, false);
} @Bean
public Queue queue002() {
return new Queue("queue002", true);// 队列持久化
} @Bean
public Binding bingding002() {
return BindingBuilder.bind(queue002()).to(topicExchange002()).with("rabbit.*");
} // 第三个,队列通过路由键绑定到第一个队列上面,即第一个交换机绑定了两个队列。
@Bean
public Queue queue003() {
return new Queue("queue003", true);// 队列持久化
} @Bean
public Binding bingding003() {
return BindingBuilder.bind(queue003()).to(topicExchange001()).with("mq.*");
} @Bean
public Queue queue_image() {
return new Queue("image_queue", true); // 队列持久
} @Bean
public Queue queue_pdf() {
return new Queue("pdf_queue", true); // 队列持久
} // RabbitTemplate,即消息模板,我们在与SpringAMQP整合的时候进行发送消息的关键类。
// 该类提供了丰富的发送消息方法,包括可靠性投递消息方法,回调监听消息接口ConfirmCallback,
// 返回值确认ReturnCallBack等等。同样我们需要进行注入到Spring容器中,然后直接使用。
// 将RabbitTemplate加入到Spring容器中
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
return rabbitTemplate;
} }

使用RabbittEmplate发送消息的案例,由于结合初始化配置文件创建的交换机,队列以及交换机和队列的绑定,将消息发送到自己创建的交换机,队列上面,所以效果请自己仔细查看,如下所示:

 package com.bie;

 import java.util.HashMap;

 import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
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; /**
*
* @author biehl
*
*/
@SpringBootTest
@RunWith(SpringRunner.class)
public class RabbitmqSpringApplicationTests { // 发送消息
@Autowired
private RabbitTemplate rabbitTemplate; @Test
public void sendMessage() {
// 1、创建消息
MessageProperties messageProperties = new MessageProperties();
messageProperties.getHeaders().put("desc", "消息描述");
messageProperties.getHeaders().put("type", "消息类型");
Message message = new Message("hello RabbitMQ".getBytes(), messageProperties); // 2、发送消息
String exchange = "topic001";
String routingKey = "spring.amqp";
rabbitTemplate.convertAndSend(exchange, routingKey, message, new MessagePostProcessor() { @Override
public Message postProcessMessage(Message message) throws AmqpException {
System.out.println("======添加额外的设置======");
message.getMessageProperties().getHeaders().put("desc", "额外的消息描述");
message.getMessageProperties().getHeaders().put("attr", "额外的属性");
return message;
}
});
} @Test
public void sendMessage2() throws Exception {
// 1 创建消息
MessageProperties messageProperties = new MessageProperties();
messageProperties.setContentType("text/plain");
Message message = new Message("RabbitMQ的消息.......".getBytes(), messageProperties); // 2、发送消息
rabbitTemplate.send("topic001", "spring.abc", message); rabbitTemplate.convertAndSend("topic001", "spring.amqp", "hello object message send!");
rabbitTemplate.convertAndSend("topic002", "rabbit.abc", "hello object message send!");
} }

运行效果如下所示:

5、SpringAMQP消息容器SimpleMessageListenerContainer。

  1)、简单消息监听器,这个类非常的强大,我们可以对他进行很多设置,对于消费者的设置项,这个类都可以满足。可以监听队列(多个队列),自动启动,自动声明功能。可以设置事务特性、事务管理器、事务属性、事务容量(并发)、是否开启事务、回滚消息等等。可以设置消费者数量、最小最大数量、批量消费等等。可以设置消息确认和自动确认模式,是否重回队列、异常捕获handler函数。可以设置消费者标签生成策略,是否独占模式,消费者属性等等。可以设置具体的监听器、消息转换器等等。
  2)、注意,SpringAMQP消息容器SimpleMessageListenerContainer可以进行动态设置,比如在运行中的应用可以动态的修改其消费者数量的大小,接收消息的模式等等。很多基于RabbitMQ的自制定化后端控制台在进行动态设置的时候,也是根据这一特性实现的。

 package com.bie;

 import java.util.UUID;

 import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
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.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.amqp.support.ConsumerTagStrategy;
import org.springframework.amqp.support.converter.ContentTypeDelegatingMessageConverter;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration; import com.bie.adapter.MessageDelegate;
import com.bie.convert.ImageMessageConverter;
import com.bie.convert.PDFMessageConverter;
import com.bie.convert.TextMessageConverter;
import com.rabbitmq.client.Channel; /**
*
* @author biehl
*
*/
@Configuration
@ComponentScan(basePackages = "com.bie")
public class RabbitMQConfig { /**
* 将ConnectionFactory注入到bean容器中
*
* @return
*/
@Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setAddresses("192.168.110.133:5672");
connectionFactory.setUsername("guest");
connectionFactory.setPassword("guest");
connectionFactory.setVirtualHost("/");
return connectionFactory;
} /**
* 参数依赖上面注入的ConnectionFactory类,所以保持参数名称和注入的ConnectionFactory一致
*
* @param connectionFactory
* @return
*/
@Bean
public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
// 注意:autoStartup必须设置为true,否则Spring容器不会加载RabbitAdmin类。
rabbitAdmin.setAutoStartup(true);
return rabbitAdmin;
} // 使用SpringAMQP去声明,就需要使用SpringAMQP的如下模式,即声明@Bean方式。
// SpringAMQP-RabbitMQ声明式配置使用 /**
* 针对消费者配置:
*
* 1. 设置交换机类型。
*
* 2. 将队列绑定到交换机。
*
* FanoutExchange: 将消息分发到所有的绑定队列,无routingkey的概念。
*
* HeadersExchange :通过添加属性key-value匹配。
*
* DirectExchange:按照routingkey分发到指定队列。
*
* TopicExchange:多关键字匹配。
*/
@Bean
public TopicExchange topicExchange001() {
return new TopicExchange("topic001", true, false);
} @Bean
public Queue queue001() {
return new Queue("queue001", true);// 队列持久化
} @Bean
public Binding bingding001() {
return BindingBuilder.bind(queue001()).to(topicExchange001()).with("spring.*");
} // 第二个交换机通过路由键绑定到队列上面。
@Bean
public TopicExchange topicExchange002() {
return new TopicExchange("topic002", true, false);
} @Bean
public Queue queue002() {
return new Queue("queue002", true);// 队列持久化
} @Bean
public Binding bingding002() {
return BindingBuilder.bind(queue002()).to(topicExchange002()).with("rabbit.*");
} // 第三个,队列通过路由键绑定到第一个队列上面,即第一个交换机绑定了两个队列。
@Bean
public Queue queue003() {
return new Queue("queue003", true);// 队列持久化
} @Bean
public Binding bingding003() {
return BindingBuilder.bind(queue003()).to(topicExchange001()).with("mq.*");
} @Bean
public Queue queue_image() {
return new Queue("image_queue", true); // 队列持久
} @Bean
public Queue queue_pdf() {
return new Queue("pdf_queue", true); // 队列持久
} // RabbitTemplate,即消息模板,我们在与SpringAMQP整合的时候进行发送消息的关键类。
// 该类提供了丰富的发送消息方法,包括可靠性投递消息方法,回调监听消息接口ConfirmCallback,
// 返回值确认ReturnCallBack等等。同样我们需要进行注入到Spring容器中,然后直接使用。
// 将RabbitTemplate加入到Spring容器中
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
return rabbitTemplate;
} /**
*
* @param connectionFactory
* @return
*/
@Bean
public SimpleMessageListenerContainer messageListenerContainer(ConnectionFactory connectionFactory) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
// 监听的队列,可变参数,可以添加多个队列。
container.setQueues(queue001(), queue002(), queue003(), queue_image(), queue_pdf());
// 设置消费者个数。
container.setConcurrentConsumers();
// 设置最大消费者个数。
container.setMaxConcurrentConsumers();
// 设置默认是否重回队列。
container.setDefaultRequeueRejected(false);
// 设置签收模式,自动签收。
container.setAcknowledgeMode(AcknowledgeMode.AUTO);
// 设置是否外露
container.setExposeListenerChannel(true);
// 设置标签策略。
container.setConsumerTagStrategy(new ConsumerTagStrategy() {
@Override
public String createConsumerTag(String queue) {
return queue + "_" + UUID.randomUUID().toString();
}
}); // 监听消息
container.setMessageListener(new ChannelAwareMessageListener() { @Override
public void onMessage(Message message, Channel channel) throws Exception {
String msg = new String(message.getBody());
System.out.println("===========================消费者消息msg : " + msg);
}
}); return container;
} }

可以直接在测试类里面进行启动,直接启动测试方法sendMessage2,如下所示:

 package com.bie;

 import java.util.HashMap;

 import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
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; /**
*
* @author biehl
*
*/
@SpringBootTest
@RunWith(SpringRunner.class)
public class RabbitmqSpringApplicationTests { @Autowired
private RabbitAdmin rabbitAdmin; @Test
public void rabbitmqAdmin() {
// 参数1交换机名称, 参数1是否持久化durable, 参数3是否自动删除 autoDelete
// 创建direct类型的交换机
DirectExchange directExchange = new DirectExchange("test.directExchange", false, false);
rabbitAdmin.declareExchange(directExchange); // 创建topic类型的交换机
TopicExchange topicExchange = new TopicExchange("test.topicExchange", false, false);
rabbitAdmin.declareExchange(topicExchange); // 创建fanout类型的交换机
FanoutExchange fanoutExchange = new FanoutExchange("test.fanoutExchange", false, false);
rabbitAdmin.declareExchange(fanoutExchange); // 创建direct类型的队列
Queue directQueue = new Queue("test.direct.queue", false);
rabbitAdmin.declareQueue(directQueue); // 创建topic类型的交队列
Queue topicQueue = new Queue("test.topic.queue", false);
rabbitAdmin.declareQueue(topicQueue); // 创建fanout类型的队列
Queue fanoutQueue = new Queue("test.fanout.queue", false);
rabbitAdmin.declareQueue(fanoutQueue); // 声明绑定
// 参数1 String destination,可以认为是具体的队列。
// 参数2 DestinationType destinationType,绑定的类型。
// 参数3 String exchange,交换机的名称。
// 参数4 String routingKey,路由键的名称。
// 参数5 Map<String, Object> arguments可以传入的参数。
// 将test.directExchange交换机和test.direct.queue队列进行绑定
rabbitAdmin.declareBinding(new Binding("test.direct.queue", Binding.DestinationType.QUEUE,
"test.directExchange", "direct", new HashMap<>())); // 将test.topicExchange交换机和test.topic.queue队列进行绑定
// rabbitAdmin.declareBinding(new Binding("test.topic.queue",
// Binding.DestinationType.QUEUE, "test.topicExchange",
// "topic", new HashMap<>()));
rabbitAdmin.declareBinding(BindingBuilder.bind(new Queue("test.topic.queue", false)) // 直接创建队列
.to(new TopicExchange("test.topicExchange", false, false)) // 直接创建交换机 建立关联关系
.with("user.#")); // 指定路由Key // 将test.fanoutExchange交换机和test.fanout.queue队列进行绑定
// rabbitAdmin.declareBinding(new Binding("test.fanout.queue",
// Binding.DestinationType.QUEUE,
// "test.fanoutExchange", "", new HashMap<>())); rabbitAdmin.declareBinding(BindingBuilder.bind(new Queue("test.fanout.queue", false)) // 直接创建队列
.to(new FanoutExchange("test.fanoutExchange", false, false))); // 直接创建交换机 建立关联关系 // 清空队列数据
rabbitAdmin.purgeQueue("test.direct.queue", false);
rabbitAdmin.purgeQueue("test.topic.queue", false);
rabbitAdmin.purgeQueue("test.fanout.queue", false);
} // 发送消息
@Autowired
private RabbitTemplate rabbitTemplate; @Test
public void sendMessage() {
// 1、创建消息
MessageProperties messageProperties = new MessageProperties();
messageProperties.getHeaders().put("desc", "消息描述");
messageProperties.getHeaders().put("type", "消息类型");
Message message = new Message("hello RabbitMQ".getBytes(), messageProperties); // 2、发送消息
String exchange = "topic001";
String routingKey = "spring.amqp";
rabbitTemplate.convertAndSend(exchange, routingKey, message, new MessagePostProcessor() { @Override
public Message postProcessMessage(Message message) throws AmqpException {
System.out.println("======添加额外的设置======");
message.getMessageProperties().getHeaders().put("desc", "额外的消息描述");
message.getMessageProperties().getHeaders().put("attr", "额外的属性");
return message;
}
});
} @Test
public void sendMessage2() throws Exception {
// 1 创建消息
MessageProperties messageProperties = new MessageProperties();
messageProperties.setContentType("text/plain");
Message message = new Message("RabbitMQ的消息.......".getBytes(), messageProperties); // 2、发送消息
rabbitTemplate.send("topic001", "spring.abc", message); rabbitTemplate.convertAndSend("topic001", "spring.amqp", "hello object message send!");
rabbitTemplate.convertAndSend("topic002", "rabbit.abc", "hello object message send!");
} }

SpringAMQP消息容器SimpleMessageListenerContainer,简单消息监听器,效果如下所示:

aaarticlea/jpeg;base64,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" alt="" />

作者:别先生

博客园:https://www.cnblogs.com/biehongli/

如果您想及时得到个人撰写文章以及著作的消息推送,可以扫描上方二维码,关注个人公众号哦。

RabbitMQ与Spring的框架整合之Spring AMQP实战的更多相关文章

  1. RabbitMQ与Spring的框架整合之Spring Boot实战

    1.RabbitMQ与Spring的框架整合之Spring Boot实战. 首先创建maven项目的RabbitMQ的消息生产者rabbitmq-springboot-provider项目,配置pom ...

  2. RabbitMQ与Spring的框架整合之Spring Cloud Stream实战

    1.RabbitMQ与Spring Cloud Stream整合实战.SpringCloud Stream整体结构核心概念图,如下所示: 图示解释:Outputs输出,即消息的发送端.Inputs输入 ...

  3. spring boot 学习(二)spring boot 框架整合 thymeleaf

    spring boot 框架整合 thymeleaf spring boot 的官方文档中建议开发者使用模板引擎,避免使用 JSP.因为若一定要使用 JSP 将无法使用. 注意:本文主要参考学习了大神 ...

  4. struts2 + spring + mybatis 框架整合详细介绍

    struts2 + spring + mybatis  框架整合详细介绍 参考地址: https://blog.csdn.net/qq_22028771/article/details/5149898 ...

  5. SSM框架-----------SpringMVC+Spring+Mybatis框架整合详细教程

    1.基本概念 1.1.Spring Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One  ...

  6. mybatis+spring+struts2框架整合

     近期公司要开发新的项目,要用struts2+mybatis+spring框架,所以学习了下,来自己的博客发表下,希望能给大家带来帮助!下边我把我的myschool开发的源代码以及数据库贴出来!  开 ...

  7. SSM框架整合( Spring 、 SpringMVC 和 Mybatis )

    1.基本概念 1.1.Spring Spring 是一个开源框架, Spring 是于 2003  年兴起的一个轻量级的 Java  开发框架,由 Rod Johnson  在其著作 Expert O ...

  8. SSM框架整合(Spring+SpringMVC+MyBatis+Oracle)

    1.开发环境搭建以及创建Maven Web项目 参看之前的博文[确保maven web项目不报错]:http://www.cnblogs.com/cainiaomahua/p/6306476.html ...

  9. SpringMVC+Spring+Hibernate框架整合原理,作用及使用方法

    转自:https://blog.csdn.net/bieleyang/article/details/77862042 SSM框架是spring MVC ,spring和mybatis框架的整合,是标 ...

随机推荐

  1. hdu 4725 The Shortest Path in Nya Graph (最短路+建图)

    The Shortest Path in Nya Graph Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  2. 2019 The Preliminary Contest for ICPC China Nanchang National Invitational(A 、H 、I 、K 、M)

    A. PERFECT NUMBER PROBLEM 题目链接:https://nanti.jisuanke.com/t/38220 题意: 输出前五个完美数 分析: 签到.直接百度完美数输出即可 #i ...

  3. 利用sklearn对多分类的每个类别进行指标评价

      今天晚上,笔者接到客户的一个需要,那就是:对多分类结果的每个类别进行指标评价,也就是需要输出每个类型的精确率(precision),召回率(recall)以及F1值(F1-score).   对于 ...

  4. Dynamics 365 Portal 多语言

    Dynamics 365 Portal 的多语言分两种情况: 1.通过定义两套记录来实现,如Web Link Set.Snippet Content,都是定义两套记录,分别关联不同的语言来实现 Web ...

  5. Flutter报错记录

    1.Could not find an option named "androidx". Run 'flutter -h' (or 'flutter   -h') for avai ...

  6. Java集合内容

    Java的集合类定义在java.util包中,支持泛型,主要提供了3种集合类,包括List,Set和Map.Java集合使用统一的Iterator遍历. 1.List遍历 实现了Iterator接口的 ...

  7. 原创 Hive count 多个度量指标,带有 distinct

    Hive  count 多个度量指标,带有  distinct ,注意点!!! 比如  select  organid, ppi, count(id1) as num1, count(distinct ...

  8. 做了这么久的程序员,你知道为什么会有 Lambda 表达式吗?

    Java8 有一些新的特性,今天老顾给大家分享一下关于 Lambda 表达式的由来,一开始感觉 Lambda 可读性蛮差的,不知道 为什么 Java8 会出来这个表达式?既然大佬们推出来,肯定是有原因 ...

  9. Path Manipulation 路径操作

  10. Java 基础复习 -- Enum 类

    一.枚举类基本语法 在 Java SE5 中添加了一个看似很小的特性,即 enum 关键字,它使得我们在需要群组并使用枚举类型集时,可以很方便的处理. 所有的 enum 都继承自 java.lang. ...