Spring 整合 RabbitMQ

1.导入依赖

1<properties> 2 3 ..... 4 5 <!-- spring --> 6 <spring.version>5.1.1.RELEASE</spring.version> 7 <!-- log4j日志包版本号 --> 8 <slf4j.version>1.7.18</slf4j.version> 9 <log4j.version>1.2.17</log4j.version> 10 </properties> 11 12 <dependencies> 13 14 <!-- Spring --> 15 <dependency> 16 <groupId>org.springframework</groupId> 17 <artifactId>spring-core</artifactId> 18 <version>${spring.version}</version> 19 </dependency> 20 <dependency> 21 <groupId>org.springframework</groupId> 22 <artifactId>spring-webmvc</artifactId> 23 <version>${spring.version}</version> 24 </dependency> 25 <dependency> 26 <groupId>org.springframework</groupId> 27 <artifactId>spring-oxm</artifactId> 28 <version>${spring.version}</version> 29 </dependency> 30 <dependency> 31 <groupId>org.springframework</groupId> 32 <artifactId>spring-tx</artifactId> 33 <version>${spring.version}</version> 34 </dependency> 35 <dependency> 36 <groupId>org.springframework</groupId> 37 <artifactId>spring-aop</artifactId> 38 <version>${spring.version}</version> 39 </dependency> 40 <dependency> 41 <groupId>org.springframework</groupId> 42 <artifactId>spring-context-support</artifactId> 43 <version>${spring.version}</version> 44 </dependency> 45 <dependency> 46 <groupId>org.springframework</groupId> 47 <artifactId>spring-test</artifactId> 48 <version>${spring.version}</version> 49 </dependency> 50 51 <!-- AOP-AspectJ spring-aop依赖 --> 52 <dependency> 53 <groupId>org.aspectj</groupId> 54 <artifactId>aspectjrt</artifactId> 55 <version>1.8.6</version> 56 </dependency> 57 <dependency> 58 <groupId>org.aspectj</groupId> 59 <artifactId>aspectjweaver</artifactId> 60 <version>1.8.6</version> 61 </dependency> 62 63 <!-- 添加日志相关jar包 --> 64 <dependency> 65 <groupId>log4j</groupId> 66 <artifactId>log4j</artifactId> 67 <version>${log4j.version}</version> 68 </dependency> 69 <dependency> 70 <groupId>org.slf4j</groupId> 71 <artifactId>slf4j-api</artifactId> 72 <version>${slf4j.version}</version> 73 </dependency> 74 <dependency> 75 <groupId>org.slf4j</groupId> 76 <artifactId>slf4j-log4j12</artifactId> 77 <version>${slf4j.version}</version> 78 </dependency> 79 80 <!-- rabbitmq --> 81 <dependency> 82 <groupId>org.springframework.amqp</groupId> 83 <artifactId>spring-rabbit</artifactId> 84 <version>1.7.5.RELEASE</version> 85 </dependency> 86 87 ..... 88 89 </dependencies>

2.创建配置文件

  a.创建 spring.xml

1<?xml version="1.0" encoding="UTF-8"?> 2<beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:aop="http://www.springframework.org/schema/aop" 5 xmlns:context="http://www.springframework.org/schema/context" 6 xsi:schemaLocation=" 7 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 8 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd 9 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 10 11 <!-- 自动扫描的包名 --> 12 <context:component-scan base-package="com.wode" /> 13 14 <!-- 开启AOP代理 --> 15 <aop:aspectj-autoproxy proxy-target-class="true" /> 16 17 <!--开启注解处理器 --> 18 <context:annotation-config> 19 </context:annotation-config> 20 21 <context:property-placeholder location="classpath:rabbit.properties"/> 22 <!-- Spring中引入其他配置文件 --> 23 <import resource="classpath*:/spring-rabbit.xml" /> 24 25</beans>

  b.创建 spring-rabbit.xml

1<?xml version="1.0" encoding="UTF-8"?> 2<beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:rabbit="http://www.springframework.org/schema/rabbit" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 6 http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit-1.2.xsd"> 7 8 <!-- ============================================公共部分============================================ --> 9 10 <!-- 创建连接类 连接安装好的 rabbitmq --> 11 <rabbit:connection-factory id="connectionFactory" host="${rabbit.ip}" port="${rabbit.port}" username="${rabbit.username}" password="${rabbit.password}" /> 12 <rabbit:admin connection-factory="connectionFactory"/> 13 14 <!-- spring amqp默认的是jackson 的一个插件,目的将生产者生产的数据转换为json存入消息队列 --> 15 <bean id="jsonMessageConverter" class="org.springframework.amqp.support.converter.Jackson2JsonMessageConverter" /> 16 17 <!-- ============================================direct路由模式============================================ --> 18 19 <!--定义消息队列,durable:是否持久化,如果想在RabbitMQ退出或崩溃的时候,不会失去所有的queue和消息,需要同时标志队列(queue)和交换机(exchange)是持久化的,即rabbit:queue标签和rabbit:direct-exchange中的durable=true,而消息(message)默认是持久化的可以看类org.springframework.amqp.core.MessageProperties中的属性public static final MessageDeliveryMode DEFAULT_DELIVERY_MODE = MessageDeliveryMode.PERSISTENT;exclusive: 仅创建者可以使用的私有队列,断开后自动删除;auto_delete: 当所有消费客户端连接断开后,是否自动删除队列 --> 20 <rabbit:queue name="direct.queue.1" id="direct.queue.1" durable="true" auto-delete="false" exclusive="false" /> 21 <rabbit:queue name="direct.queue.2" id="direct.queue.2" durable="true" auto-delete="false" exclusive="false" /> 22 23 <!--绑定队列,rabbitmq的exchangeType常用的三种模式:direct,fanout,topic三种,我们用direct模式,即rabbit:direct-exchange标签,Direct交换器很简单,如果是Direct类型,就会将消息中的RoutingKey与该Exchange关联的所有Binding中的BindingKey进行比较,如果相等,则发送到该Binding对应的Queue中。有一个需要注意的地方:如果找不到指定的exchange,就会报错。但routing key找不到的话,不会报错,这条消息会直接丢失,所以此处要小心,auto-delete:自动删除,如果为Yes,则该交换机所有队列queue删除后,自动删除交换机,默认为false --> 24 <rabbit:direct-exchange id="direct.exchange" name="direct.exchange" durable="true" auto-delete="false"> 25 <rabbit:bindings> 26 <rabbit:binding queue="direct.queue.1" key="${routing.1}"></rabbit:binding> 27 <rabbit:binding queue="direct.queue.2" key="${routing.2}"></rabbit:binding> 28 </rabbit:bindings> 29 </rabbit:direct-exchange> 30 31 <rabbit:template exchange="direct.exchange" id="rabbitTemplate" connection-factory="connectionFactory" message-converter="jsonMessageConverter" /> 32 33 <!-- 消费者部分 --> 34 <!-- 自定义接口类 --> 35 <bean id="directConsumerAuto" class="com.wode.direct.DirectConsumerAuto"></bean> 36 <bean id="directConsumerManual" class="com.wode.direct.DirectConsumerManual"></bean> 37 38 <!-- 配置监听acknowledeg="manual"设置手动应答,它能够保证即使在一个worker处理消息的时候用CTRL+C来杀掉这个worker,或者一个consumer挂了(channel关闭了、connection关闭了或者TCP连接断了),也不会丢失消息。因为RabbitMQ知道没发送ack确认消息导致这个消息没有被完全处理,将会对这条消息做re-queue处理。如果此时有另一个consumer连接,消息会被重新发送至另一个consumer会一直重发,直到消息处理成功,监听容器acknowledge="auto" concurrency="30"设置发送次数,最多发送30--> 39 <rabbit:listener-container connection-factory="connectionFactory" acknowledge="auto" concurrency="20"> 40 <rabbit:listener queues="direct.queue.1" ref="directConsumerAuto" /> 41 </rabbit:listener-container> 42 <rabbit:listener-container connection-factory="connectionFactory" acknowledge="manual" concurrency="20"> 43 <rabbit:listener queues="direct.queue.2" ref="directConsumerManual" /> 44 </rabbit:listener-container> 45 46 47 <!-- ============================================fanout订阅推送模式============================================ --> 48 49 <!--定义消息队列--> 50 <rabbit:queue name="fanout.queue.1" id="fanout.queue.1" durable="true" auto-delete="false" exclusive="false" /> 51 <rabbit:queue name="fanout.queue.2" id="fanout.queue.2" durable="true" auto-delete="false" exclusive="false" /> 52 53 <!-- Fanout 扇出,顾名思义,就是像风扇吹面粉一样,吹得到处都是。如果使用fanout类型的exchange,那么routing key就不重要了。因为凡是绑定到这个exchange的queue,都会受到消息。 --> 54 <rabbit:fanout-exchange id="fanout.exchange" name="fanout.exchange" durable="true" auto-delete="false"> 55 <rabbit:bindings> 56 <rabbit:binding queue="fanout.queue.1"></rabbit:binding> 57 <rabbit:binding queue="fanout.queue.2"></rabbit:binding> 58 </rabbit:bindings> 59 </rabbit:fanout-exchange> 60 61 <rabbit:template exchange="fanout.exchange" id="fanoutRabbitTemplate" connection-factory="connectionFactory" message-converter="jsonMessageConverter" /> 62 63 <!-- 消费者部分 --> 64 <!-- 自定义接口类 --> 65 <bean id="fanoutConsumerAuto" class="com.wode.fanout.FanoutConsumerAuto"></bean> 66 <bean id="fanoutConsumerManual" class="com.wode.fanout.FanoutConsumerManual"></bean> 67 68 <!-- 配置监听acknowledeg="manual"设置手动应答,它能够保证即使在一个worker处理消息的时候用CTRL+C来杀掉这个worker,或者一个consumer挂了(channel关闭了、connection关闭了或者TCP连接断了),也不会丢失消息。因为RabbitMQ知道没发送ack确认消息导致这个消息没有被完全处理,将会对这条消息做re-queue处理。如果此时有另一个consumer连接,消息会被重新发送至另一个consumer会一直重发,直到消息处理成功,监听容器acknowledge="auto" concurrency="30"设置发送次数,最多发送30--> 69 <rabbit:listener-container connection-factory="connectionFactory" acknowledge="auto" concurrency="20"> 70 <rabbit:listener queues="fanout.queue.1" ref="fanoutConsumerAuto" /> 71 </rabbit:listener-container> 72 <rabbit:listener-container connection-factory="connectionFactory" acknowledge="manual" concurrency="20"> 73 <rabbit:listener queues="fanout.queue.2" ref="fanoutConsumerManual" /> 74 </rabbit:listener-container> 75 76 77 <!-- ============================================topic模式============================================ --> 78 79 <!--定义消息队列--> 80 <rabbit:queue name="topic.queue.1" id="topic.queue.1" durable="true" auto-delete="false" exclusive="false" /> 81 <rabbit:queue name="topic.queue.2" id="topic.queue.2" durable="true" auto-delete="false" exclusive="false" /> 82 83 <!-- 发送端不是按固定的routing key发送消息,而是按字符串“匹配”发送,接收端同样如此 --> 84 <rabbit:topic-exchange id="topic.exchange" name="topic.exchange" durable="true" auto-delete="false"> 85 <rabbit:bindings> 86 <rabbit:binding queue="topic.queue.1" pattern="order.*" /> 87 <rabbit:binding queue="topic.queue.2" pattern="*.insert" /> 88 </rabbit:bindings> 89 </rabbit:topic-exchange> 90 91 <rabbit:template exchange="topic.exchange" id="topicRabbitTemplate" connection-factory="connectionFactory" message-converter="jsonMessageConverter" /> 92 93 <!-- 消费者部分 --> 94 <!-- 自定义接口类 --> 95 <bean id="topicConsumerAuto" class="com.wode.topic.TopicConsumerAuto"></bean> 96 <bean id="topicConsumerManual" class="com.wode.topic.TopicConsumerManual"></bean> 97 98 <!-- 配置监听acknowledeg="manual"设置手动应答,它能够保证即使在一个worker处理消息的时候用CTRL+C来杀掉这个worker,或者一个consumer挂了(channel关闭了、connection关闭了或者TCP连接断了),也不会丢失消息。因为RabbitMQ知道没发送ack确认消息导致这个消息没有被完全处理,将会对这条消息做re-queue处理。如果此时有另一个consumer连接,消息会被重新发送至另一个consumer会一直重发,直到消息处理成功,监听容器acknowledge="auto" concurrency="30"设置发送次数,最多发送30--> 99 <rabbit:listener-container connection-factory="connectionFactory" acknowledge="auto" concurrency="20"> 100 <rabbit:listener queues="topic.queue.1" ref="topicConsumerAuto" /> 101 </rabbit:listener-container> 102 <rabbit:listener-container connection-factory="connectionFactory" acknowledge="manual" concurrency="20"> 103 <rabbit:listener queues="topic.queue.2" ref="topicConsumerManual" /> 104 </rabbit:listener-container> 105 106 107</beans>

  c.创建 rabbit.properties

1#RabbitMQ服务器地址,默认值"localhost" 2rabbit.ip=localhost 3#RabbitMQ服务端口,默认值为5672 4rabbit.port=5672 5#访问RabbitMQ服务器的账户,默认是guest 6rabbit.username=guest 7#访问RabbitMQ服务器的密码,默认是guest 8rabbit.password=guest 9 10#路由标识 11routing.1=1 12routing.2=2

3.创建生产者

1import org.springframework.amqp.core.AmqpTemplate; 2import org.springframework.beans.factory.annotation.Value; 3import org.springframework.stereotype.Component; 4 5import javax.annotation.Resource; 6 7@Component 8public class CommonProducer { 9 10 //direct模式 11 @Resource(name = "rabbitTemplate") 12 private AmqpTemplate rabbitTemplate; 13 14 @Value("${routing.1}") 15 private String routing1; 16 @Value("${routing.2}") 17 private String routing2; 18 19 //fanout模式 20 @Resource(name = "fanoutRabbitTemplate") 21 private AmqpTemplate fanoutRabbitTemplate; 22 23 //topic模式 24 @Resource(name = "topicRabbitTemplate") 25 private AmqpTemplate topicRabbitTemplate; 26 27 28 public void send(){ 29 rabbitTemplate.convertAndSend(routing1, "routing1"); 30 rabbitTemplate.convertAndSend(routing2, "routing2"); 31 32 fanoutRabbitTemplate.convertAndSend("fanoutMsg"); 33 34 topicRabbitTemplate.convertAndSend("order.insert", "order.insert"); 35 topicRabbitTemplate.convertAndSend("order.update", "order.update"); 36 } 37 38}

4.创建direct模式消费者

  a.自动提交消费者,对应配置文件中 acknowledge="auto"

1import com.rabbitmq.client.Channel; 2import org.springframework.amqp.core.Message; 3import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener; 4 5public class DirectConsumerAuto implements ChannelAwareMessageListener { 6 @Override 7 public void onMessage(Message message, Channel channel) throws Exception { 8 String msg = new String(message.getBody(),"UTF-8"); 9 System.out.println("[DirectConsumerAuto]消费者接收到:" + msg); 10 } 11}

  b.手动提交消费者,对应配置文件中 acknowledge="manual"

1import com.rabbitmq.client.Channel; 2import org.springframework.amqp.core.Message; 3import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener; 4 5public class DirectConsumerManual implements ChannelAwareMessageListener { 6 @Override 7 public void onMessage(Message message, Channel channel) throws Exception { 8 String msg = new String(message.getBody(),"UTF-8"); 9 System.out.println("[DirectConsumerManual]消费者接收到:" + msg); 10 //手动确认 11 channel.basicAck(message.getMessageProperties().getDeliveryTag(), true); 12 } 13}

5.创建fanout模式消费者

  a.自动提交消费者,对应配置文件中 acknowledge="auto"

1import com.rabbitmq.client.Channel; 2import org.springframework.amqp.core.Message; 3import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener; 4 5public class FanoutConsumerAuto implements ChannelAwareMessageListener { 6 @Override 7 public void onMessage(Message message, Channel channel) throws Exception { 8 String msg = new String(message.getBody(),"UTF-8"); 9 System.out.println("[FanoutConsumerAuto]消费者接收到:" + msg); 10 } 11}

  b.手动提交消费者,对应配置文件中 acknowledge="manual"

1import com.rabbitmq.client.Channel; 2import org.springframework.amqp.core.Message; 3import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener; 4 5public class FanoutConsumerManual implements ChannelAwareMessageListener { 6 @Override 7 public void onMessage(Message message, Channel channel) throws Exception { 8 String msg = new String(message.getBody(),"UTF-8"); 9 System.out.println("[FanoutConsumerManual]消费者接收到:" + msg); 10 //手动确认 11 channel.basicAck(message.getMessageProperties().getDeliveryTag(), true); 12 } 13}

6.创建topic模式消费者

  a.自动提交消费者,对应配置文件中 acknowledge="auto"

1import com.rabbitmq.client.Channel; 2import org.springframework.amqp.core.Message; 3import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener; 4 5public class TopicConsumerAuto implements ChannelAwareMessageListener { 6 @Override 7 public void onMessage(Message message, Channel channel) throws Exception { 8 String msg = new String(message.getBody(),"UTF-8"); 9 System.out.println("[TopicConsumerAuto]消费者接收到:" + msg); 10 } 11}

  b.手动提交消费者,对应配置文件中 acknowledge="manual"

1import com.rabbitmq.client.Channel; 2import org.springframework.amqp.core.Message; 3import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener; 4 5public class TopicConsumerManual implements ChannelAwareMessageListener { 6 @Override 7 public void onMessage(Message message, Channel channel) throws Exception { 8 String msg = new String(message.getBody(),"UTF-8"); 9 System.out.println("[TopicConsumerManual]消费者接收到:" + msg); 10 //手动确认 11 channel.basicAck(message.getMessageProperties().getDeliveryTag(), true); 12 } 13}

7.测试

1public static void main(String[] args) { 2 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml"); 3 CommonProducer commonProducer = (CommonProducer) applicationContext.getBean("commonProducer"); 4 commonProducer.send(); 5 }
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )