前言
RabbitMQ单独使用的场景现在非常少,基本都是整合在Spring中,接下来我们就针对SpringBoot如何整合RabbitMQ进行说明
整合
1. 导入依赖包(Gradle)
compile('org.springframework.boot:spring-boot-starter-amqp')
2. 配置文件设置(application.properties)
spring.rabbitmq.host=47.105.72.224 spring.rabbitmq.port=5672 spring.rabbitmq.username=rabbitmq spring.rabbitmq.password=rabbitmq spring.rabbitmq.virtual-host=/my
3. SpringBoot提供和模板对象(RabbitTemplate)。
4. 案例1: 直连。
生产者:
import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class ProviderMQ { @Autowired RabbitTemplate rabbitTemplate; public void sendMessage(){ rabbitTemplate.convertAndSend("hello","hello world!"); } }
消费者:SpringBoot启动自动会创建线程监听消息
import org.springframework.amqp.rabbit.annotation.Queue; import org.springframework.amqp.rabbit.annotation.RabbitHandler; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.stereotype.Component; /** * 使用注解设置队列:@Queue * value 为队列名 * durable 为是否持久化 默认值是true * autoDelete 是否自动删除队列 默认值是false */ @Component @RabbitListener(queuesToDeclare = @Queue(value = "hello",durable = "true",autoDelete = "true")) public class CustomerMQ { @RabbitHandler public void receiveMessage(String message){ System.out.println("接收到的消息:"+message); } }
测试类:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.io.IOException; import java.util.concurrent.TimeoutException; @RestController public class Test { @Autowired ProviderMQ provider; @RequestMapping("/Send.do") public String workSend() throws IOException, TimeoutException { provider.sendMessage(); return "success"; } }
运行结果:
案例2: work queue
生产者:
import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class WorkProviderMQ { @Autowired RabbitTemplate rabbitTemplate; public void sendMessage(){ for (int i = 0; i < 10; i++) { rabbitTemplate.convertAndSend("work","第"+i+"个消息:hello work!"); } } }
消费者:
import org.springframework.amqp.rabbit.annotation.Queue; import org.springframework.amqp.rabbit.annotation.RabbitHandler; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.stereotype.Component; /** * 使用注解设置队列:@Queue * value 为队列名 * durable 为是否持久化 默认值是true * autoDelete 是否自动删除队列 默认值是false */ @Component public class WorkCustomerMQ { @RabbitListener(queuesToDeclare = @Queue(value = "work")) public void receiveMessage1(String message){ System.out.println("接收到的消息1:"+message); } @RabbitListener(queuesToDeclare = @Queue(value = "work")) public void receiveMessage2(String message){ System.out.println("接收到的消息2:"+message); } }
运行结果:
案例3: 广播(fanout)
生产者:
import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class FanoutProviderMQ { @Autowired RabbitTemplate rabbitTemplate; public void sendMessage(){ rabbitTemplate.convertAndSend("fanoutMessage","","fanout消息:hello fanout!"); } }
消费者:
import org.springframework.amqp.rabbit.annotation.Exchange; import org.springframework.amqp.rabbit.annotation.Queue; import org.springframework.amqp.rabbit.annotation.QueueBinding; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.stereotype.Component; /** * 使用注解设置队列:@Queue * value 为队列名 * durable 为是否持久化 默认值是true * autoDelete 是否自动删除队列 默认值是false */ @Component public class FanoutCustomerMQ { /** * @Queue 不加value 表示临时队列 * @param message */ @RabbitListener(bindings = {@QueueBinding(value = @Queue,exchange = @Exchange(value = "fanoutMessage",type = "fanout"))}) public void receiveMessage1(String message){ System.out.println("接收到的消息1:"+message); } @RabbitListener(bindings = {@QueueBinding(value = @Queue,exchange = @Exchange(value = "fanoutMessage",type = "fanout"))}) public void receiveMessage2(String message){ System.out.println("接收到的消息2:"+message); } }
运行结果:
案例4: 订阅(Routing)
生产者:
import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class DirectProviderMQ { @Autowired RabbitTemplate rabbitTemplate; public void sendMessage(){ rabbitTemplate.convertAndSend("directMessage","info","direct消息:hello info!"); rabbitTemplate.convertAndSend("directMessage","error","direct消息:hello error!"); rabbitTemplate.convertAndSend("directMessage","warn","direct消息:hello warn!"); } }
消费者:
import org.springframework.amqp.rabbit.annotation.Exchange; import org.springframework.amqp.rabbit.annotation.Queue; import org.springframework.amqp.rabbit.annotation.QueueBinding; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.stereotype.Component; /** * 使用注解设置队列:@Queue * value 为队列名 * durable 为是否持久化 默认值是true * autoDelete 是否自动删除队列 默认值是false */ @Component public class DirectCustomerMQ { /** * @Queue 不加value 表示临时队列 * type = "direct" direct 是默认模式 * @param message */ @RabbitListener(bindings = {@QueueBinding(value = @Queue,exchange = @Exchange(value = "directMessage",type = "direct"),key = {"info","error"})}) public void receiveMessage1(String message){ System.out.println("接收到的消息1:"+message); } @RabbitListener(bindings = {@QueueBinding(value = @Queue,exchange = @Exchange(value = "directMessage",type = "direct"),key = {"warn"})}) public void receiveMessage2(String message){ System.out.println("接收到的消息2:"+message); } }
运行结果:
案例5:动态订阅(Topic)
生产者:
import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class TopicProviderMQ { @Autowired RabbitTemplate rabbitTemplate; public void sendMessage(){ rabbitTemplate.convertAndSend("topicMessage","user.info","direct消息:hello user.info!"); rabbitTemplate.convertAndSend("topicMessage","user.error","direct消息:hello user.error!"); rabbitTemplate.convertAndSend("topicMessage","user.warn","direct消息:hello user.warn!"); rabbitTemplate.convertAndSend("topicMessage","user.warn.message","direct消息:hello user.warn.message!"); } }
消费者:
import org.springframework.amqp.rabbit.annotation.Exchange; import org.springframework.amqp.rabbit.annotation.Queue; import org.springframework.amqp.rabbit.annotation.QueueBinding; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.stereotype.Component; /** * 使用注解设置队列:@Queue * value 为队列名 * durable 为是否持久化 默认值是true * autoDelete 是否自动删除队列 默认值是false */ @Component public class TopicCustomerMQ { /** * @Queue 不加value 表示临时队列 * type = "direct" direct 是默认模式 * @param message */ @RabbitListener(bindings = {@QueueBinding(value = @Queue,exchange = @Exchange(value = "topicMessage",type = "topic"),key = {"*.info"})}) public void receiveMessage1(String message){ System.out.println("接收到的消息1:"+message); } @RabbitListener(bindings = {@QueueBinding(value = @Queue,exchange = @Exchange(value = "topicMessage",type = "topic"),key = {"user.*"})}) public void receiveMessage2(String message){ System.out.println("接收到的消息2:"+message); } @RabbitListener(bindings = {@QueueBinding(value = @Queue,exchange = @Exchange(value = "topicMessage",type = "topic"),key = {"user.#"})}) public void receiveMessage3(String message){ System.out.println("接收到的消息3:"+message); } }
运行结果:
总结
1. SpringBoot 整合RabbitMQ步骤。
2. 简化了配置逻辑。
3. 启动系统,消费者也自动被启动。
4. Spring提供了RabbitTemplate来封装MQ,最终简化我们代码。
5. 相关注解需要掌握。