实战背景:用一篇文章能实战说明,SpringBoot+RabbitMQ的集成,因为涉及到安装和代码编写的知识点,从如下七步法,构建工程,具体关系如下:
工程需求:发送和接收消息
业务分析:安装MQ,然后集成SpringBoot
准备工作:
第一步:需要下载安装erlong环境。地址是:http://www.erlang.org/downloads
里面有windows和linux,测试环境是windows所以下载的是OTP 20.2 Windows 64-bit Binary File
第二步:下载安装rabbitMQ
同理下载windows版本的。下载地址:http://www.rabbitmq.com/download.html,选择window installer
安装完成后,进入C:\Program Files\RabbitMQ Server\rabbitmq_server-3.8.6\sbin目录,执行如下命令
rabbitmq-service.bat stop
rabbitmq-service.bat install
rabbitmq-service.bat start
第三步:rabbitmq自带管理后台,安装后需要配置开启
进入rabbitmq安装目录中的sbin目录执行
rabbitmq-plugins enable rabbitmq_management
重启rabbitmq服务生效
打开http://localhost:15672/即可看到管理后台
用户名密码均为guest
实战开始了!!!
第一步;构建工程
第二步:构建pom.xml文件
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Rabbitmq_QueueDemo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<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>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
第三步:构建application.properties文件
spring.application.name=rabbitmq-hello
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
第四步:配置队列
package com.example.demo.config;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author changyaobin
* @data 2/25/2019 7:31 PM
*/
@Configuration
public class RabbitmqConfig {
@Bean
public Queue queue() {
return new Queue("Queue1");
}
}
第五步:创建接收者
package com.example.demo.mq;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* @author 常耀斌
* @data 2019/02/03 11:07
*/
@Component
@RabbitListener(queues = "Queue1")//监听QueueHello的消息队列
public class ReceiverA {
@RabbitHandler//@RabbitHandler来实现具体消费
public void QueueReceiver(String Queue1) {
System.out.println("Receiver A: " + Queue1);
}
}
第六步:创建发送者
package com.example.demo.mq;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* @author changyaobin
* @data 2019/02/03 11:06
* rabbitTemplate是springboot 提供的默认实现
*/
@Component
public class SenderA {
@Autowired
private AmqpTemplate rabbitTemplate;
public void send(String context) {
System.out.println("Sender : " + context);
//使用AmqpTemplate将消息发送到消息队列QueueHello中去
this.rabbitTemplate.convertAndSend("Queue1", context);
}
}
第七步:单元测试
package com.example.demo.controller;
import com.example.demo.mq.SenderA;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.retry.backoff.Sleeper;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Date;
/**
* Copyright (C), 2019-2019, XXX有限公司
* FileName: QueueSendTest
* Author: 常耀斌
* Date: 2019/4/22 22:22
*
* @Description: $description$
* History:
* <author> <time> <version> <desc>
* 作者姓名 修改时间 版本号 描述
*/
@SpringBootTest
@RunWith(SpringRunner.class)
public class MQTest {
/**
* @Description: 测试发送和接收队列
*/
@Autowired
private SenderA queueSender;
@Autowired
private AmqpTemplate amqpTemplate;
@Test
public void QueueSend() {
int i = 2;
for (int j = 0; j < i; j++) {
String msg = "Queue1 msg" + j + new Date();
try {
queueSender.send(msg);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Test
public void send() {
Message message = MessageBuilder.withBody("body content".getBytes())
.setContentType(MessageProperties.CONTENT_TYPE_TEXT_PLAIN)
.setMessageId("1")
.setHeader("header", "header")
.build();
amqpTemplate.send("Queue1", message);
amqpTemplate.convertAndSend("Queue1", "body content");
}
}
第四步:结果展示
13:08:07.051 [main] DEBUG org.springframework.test.context.junit4.SpringJUnit4ClassRunner - SpringJUnit4ClassRunner constructor called with [class com.example.demo.controller.MQTest]
13:08:07.058 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating CacheAwareContextLoaderDelegate from class [org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate]
13:08:07.067 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating BootstrapContext using constructor [public org.springframework.test.context.support.DefaultBootstrapContext(java.lang.Class,org.springframework.test.context.CacheAwareContextLoaderDelegate)]
13:08:07.084 [main] DEBUG org.springframework.test.context.BootstrapUtils - Instantiating TestContextBootstrapper for test class [com.example.demo.controller.MQTest] from class [org.springframework.boot.test.context.SpringBootTestContextBootstrapper]
13:08:07.094 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Neither @ContextConfiguration nor @ContextHierarchy found for test class [com.example.demo.controller.MQTest], using SpringBootContextLoader
13:08:07.098 [main] DEBUG org.springframework.test.context.support.AbstractContextLoader - Did not detect default resource location for test class [com.example.demo.controller.MQTest]: class path resource [com/example/demo/controller/MQTest-context.xml] does not exist
13:08:07.098 [main] DEBUG org.springframework.test.context.support.AbstractContextLoader - Did not detect default resource location for test class [com.example.demo.controller.MQTest]: class path resource [com/example/demo/controller/MQTestContext.groovy] does not exist
13:08:07.098 [main] INFO org.springframework.test.context.support.AbstractContextLoader - Could not detect default resource locations for test class [com.example.demo.controller.MQTest]: no resource found for suffixes {-context.xml, Context.groovy}.
13:08:07.099 [main] INFO org.springframework.test.context.support.AnnotationConfigContextLoaderUtils - Could not detect default configuration classes for test class [com.example.demo.controller.MQTest]: MQTest does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
13:08:07.136 [main] DEBUG org.springframework.test.context.support.ActiveProfilesUtils - Could not find an 'annotation declaring class' for annotation type [org.springframework.test.context.ActiveProfiles] and class [com.example.demo.controller.MQTest]
13:08:07.199 [main] DEBUG org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider - Identified candidate component class: file [D:\book\Spring-Boot-Book\12\Rabbitmq_QueueDemo\target\classes\com\example\demo\RabbitmqDelayedDemoApplication.class]
13:08:07.200 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Found @SpringBootConfiguration com.example.demo.RabbitmqDelayedDemoApplication for test class com.example.demo.controller.MQTest
13:08:07.272 [main] DEBUG org.springframework.boot.test.context.SpringBootTestContextBootstrapper - @TestExecutionListeners is not present for class [com.example.demo.controller.MQTest]: using defaults.
13:08:07.273 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener, org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]
13:08:07.284 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper - Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@48aaecc3, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@7c0c77c7, org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener@7adda9cc, org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener@5cee5251, org.springframework.test.context.support.DirtiesContextTestExecutionListener@433d61fb, org.springframework.test.context.transaction.TransactionalTestExecutionListener@5c909414, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@4b14c583, org.springframework.boot.test.mock.mockito.ResetMocksTestExecutionListener@65466a6a, org.springframework.boot.test.autoconfigure.restdocs.RestDocsTestExecutionListener@4ddced80, org.springframework.boot.test.autoconfigure.web.client.MockRestServiceServerResetTestExecutionListener@1534f01b, org.springframework.boot.test.autoconfigure.web.servlet.MockMvcPrintOnlyOnFailureTestExecutionListener@78e117e3, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverTestExecutionListener@2ea227af]
13:08:07.286 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved @ProfileValueSourceConfiguration [null] for test class [com.example.demo.controller.MQTest]
13:08:07.286 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved ProfileValueSource type [class org.springframework.test.annotation.SystemProfileValueSource] for class [com.example.demo.controller.MQTest]
13:08:07.294 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved @ProfileValueSourceConfiguration [null] for test class [com.example.demo.controller.MQTest]
13:08:07.294 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved ProfileValueSource type [class org.springframework.test.annotation.SystemProfileValueSource] for class [com.example.demo.controller.MQTest]
13:08:07.295 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved @ProfileValueSourceConfiguration [null] for test class [com.example.demo.controller.MQTest]
13:08:07.295 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved ProfileValueSource type [class org.springframework.test.annotation.SystemProfileValueSource] for class [com.example.demo.controller.MQTest]
13:08:07.296 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved @ProfileValueSourceConfiguration [null] for test class [com.example.demo.controller.MQTest]
13:08:07.296 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved ProfileValueSource type [class org.springframework.test.annotation.SystemProfileValueSource] for class [com.example.demo.controller.MQTest]
13:08:07.300 [main] DEBUG org.springframework.test.context.support.AbstractDirtiesContextTestExecutionListener - Before test class: context [DefaultTestContext@3e92efc3 testClass = MQTest, testInstance = [null], testMethod = [null], testException = [null], mergedContextConfiguration = [WebMergedContextConfiguration@1622f1b testClass = MQTest, locations = '{}', classes = '{class com.example.demo.RabbitmqDelayedDemoApplication}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}', contextCustomizers = set[org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@55d56113, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@10bdf5e5, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@13a5fe33, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@1d16f93d], resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map['org.springframework.test.context.web.ServletTestExecutionListener.activateListener' -> true]], class annotated with @DirtiesContext [false] with mode [null].
13:08:07.301 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved @ProfileValueSourceConfiguration [null] for test class [com.example.demo.controller.MQTest]
13:08:07.301 [main] DEBUG org.springframework.test.annotation.ProfileValueUtils - Retrieved ProfileValueSource type [class org.springframework.test.annotation.SystemProfileValueSource] for class [com.example.demo.controller.MQTest]
13:08:07.317 [main] DEBUG org.springframework.test.context.support.TestPropertySourceUtils - Adding inlined properties to environment: {spring.jmx.enabled=false, org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true, server.port=-1}
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.4.RELEASE)
2020-08-14 13:08:07.509 INFO 924 --- [ main] com.example.demo.controller.MQTest : Starting MQTest on LAPTOP-SKR0DDE6 with PID 924 (started by cyb in D:\book\Spring-Boot-Book\12\Rabbitmq_QueueDemo)
2020-08-14 13:08:07.510 INFO 924 --- [ main] com.example.demo.controller.MQTest : No active profile set, falling back to default profiles: default
2020-08-14 13:08:08.956 INFO 924 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-08-14 13:08:09.306 INFO 924 --- [ main] o.s.a.r.c.CachingConnectionFactory : Attempting to connect to: [localhost:5672]
2020-08-14 13:08:09.418 INFO 924 --- [ main] o.s.a.r.c.CachingConnectionFactory : Created new connection: rabbitConnectionFactory#5769e7ae:0/SimpleConnection@782168b7 [delegate=amqp://[email protected]:5672/, localPort= 64548]
2020-08-14 13:08:09.460 INFO 924 --- [ main] com.example.demo.controller.MQTest : Started MQTest in 2.136 seconds (JVM running for 2.727)
Sender : Queue1 msg0Fri Aug 14 13:08:09 CST 2020
Sender : Queue1 msg1Fri Aug 14 13:08:09 CST 2020
2020-08-14 13:08:09.612 INFO 924 --- [ Thread-2] o.s.a.r.l.SimpleMessageListenerContainer : Waiting for workers to finish.
Receiver A: Queue1 msg0Fri Aug 14 13:08:09 CST 2020
Receiver B: Queue1 msg1Fri Aug 14 13:08:09 CST 2020
2020-08-14 13:08:09.619 INFO 924 --- [ Thread-2] o.s.a.r.l.SimpleMessageListenerContainer : Successfully waited for workers to finish.
2020-08-14 13:08:09.620 INFO 924 --- [ Thread-2] o.s.a.r.l.SimpleMessageListenerContainer : Waiting for workers to finish.
2020-08-14 13:08:10.621 INFO 924 --- [ Thread-2] o.s.a.r.l.SimpleMessageListenerContainer : Successfully waited for workers to finish.
2020-08-14 13:08:10.629 INFO 924 --- [ Thread-2] o.s.a.r.l.SimpleMessageListenerContainer : Shutdown ignored - container is not active already
2020-08-14 13:08:10.629 INFO 924 --- [ Thread-2] o.s.a.r.l.SimpleMessageListenerContainer : Shutdown ignored - container is not active already
2020-08-14 13:08:10.630 INFO 924 --- [ Thread-2] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'