Spring整合
发布者
依赖:
org.springframework.amqp
spring-rabbit
2.1.8.RELEASE
配置文件配置
rabbitmq.host=192.168.88.3
rabbitmq.port=5672
rabbitmq.username=lyd
rabbitmq.password=lyd
rabbitmq.virtual-host=/yd
XML配置
加载配置文件
<context:property-placeholder location="classpath:rabbitmq.properties"/>
定义连接
<rabbit:connection-factory id="connectionFactory" host="81.71.140.7"
port="${rabbitmq.port}"
username="${rabbitmq.username}"
password="${rabbitmq.password}"
virtual-host="${rabbitmq.virtual-host}"/>
定义管理交换机、队列
<rabbit:admin connection-factory="connectionFactory"/>
定义rabbitTemplate对象操作可以在代码中方便发送消息
<rabbit:template id="rabbitTemplate" connection-factory="connectionFactory"/>
以上配置为5种模式下均要使用的公共配置
定义持久化队列,不存在则自动创建;不绑定到交换机则绑定到默认交换机
默认交换机类型为direct,名字为:"",路由键为队列的名称;
id:bean的名称
name:queue的名称
auto-declare:自动创建
auto-delete:自动删除。 最后一个消费者和该队列断开连接后,自动删除队列
durable:是否持久化
1、hello world和工作队列模式(跟本上来说这两种是一样的,其发布者的配置是一样的)
<rabbit:queue id="spring_queue" name="spring_queue" auto-declare="true"/>
2、广播模式
广播模式需要定义交换机,这边定义两个队列
<rabbit:queue id="spring_fanout_queue_1" name="spring_fanout_queue_1" auto-declare="true"/>
<rabbit:queue id="spring_fanout_queue_2" name="spring_fanout_queue_2" auto-declare="true"/>
<rabbit:fanout-exchange id="spring_fanout_exchange" name="spring_fanout_exchange" auto-declare="true">
<rabbit:bindings>
<rabbit:binding queue="spring_fanout_queue_1" />
<rabbit:binding queue="spring_fanout_queue_2"/>
</rabbit:bindings>
</rabbit:fanout-exchange>
交换机名:spring_fanout_exchange
列名:spring_fanout_queue_1,spring_fanout_queue_2
3、路由模式
<rabbit:queue id="spring_direct_queue" name="spring_direct_queue" auto-declare="true"/>
<rabbit:direct-exchange name="spring_direct_exchange" >
<rabbit:bindings>
<rabbit:binding queue="spring_direct_queue" key="info"></rabbit:binding>
</rabbit:bindings>
</rabbit:direct-exchange
队列名:spring_direct_queue
交换机名:spring_direct_exchange
路由key:info
4、通配符模式
<rabbit:queue id="spring_topic_queue_star" name="spring_topic_queue_star" auto-declare="true"/>
<rabbit:queue id="spring_topic_queue_well" name="spring_topic_queue_well" auto-declare="true"/>
<rabbit:queue id="spring_topic_queue_well2" name="spring_topic_queue_well2" auto-declare="true"/>
<rabbit:topic-exchange id="spring_topic_exchange" name="spring_topic_exchange" auto-declare="true">
<rabbit:bindings>
<rabbit:binding pattern="aaa.*" queue="spring_topic_queue_star"/>
<rabbit:binding pattern="bbb.#" queue="spring_topic_queue_well"/>
<rabbit:binding pattern="cccc.#" queue="spring_topic_queue_well2"/>
</rabbit:bindings>
</rabbit:topic-exchange>
java实现
@Autowired
private RabbitTemplate rabbitTemplate;
1、rabbitTemplate.convertAndSend(“spring_queue”,“hello world spring…”);
队列名:spring_queue
发送的消息:hello world spring…
2、rabbitTemplate.convertAndSend(“spring_fanout_exchange”,"",“spring fanout…”);
3、rabbitTemplate.convertAndSend(“spring_direct_exchange”,“info”,“spring Direct…”);
4、rabbitTemplate.convertAndSend(“spring_topic_exchange”,“aaa.hehe.haha”,“spring topic…”);
convertAndSend方法的参数:
第一个:交换机名
第二个:key名
第三个:发送的消息
消费者
依赖及配置文件与发布者一样,加载配置文件及定义连接的也一样
XML配置:
5种模式均采用以下发送即可接收消息
<bean id="springQueueListener" class="com.rabbitmq.listener.SpringQueueListener"/>
<rabbit:listener-container connection-factory="connectionFactory" auto-declare="true">
<rabbit:listener ref="springQueueListener" queue-names="spring_queue"/>
</rabbit:listener-container>
添加SpringQueueListener类,需要实现MessageListener接口即可;
public class SpringQueueListener implements MessageListener {
@Override
public void onMessage(Message message) {
//打印消息
System.out.println(new String(message.getBody()));
}
}
消息可靠性投递
定义连接的时候添加消息可靠性投递选项
publisher-confirms和publisher-returns为true即可
<rabbit:connection-factory id="connectionFactory" host="81.71.140.7"
port="${rabbitmq.port}"
username="${rabbitmq.username}"
password="${rabbitmq.password}"
virtual-host="${rabbitmq.virtual-host}"
publisher-confirms="true"
publisher-returns="true"
/>
这里以路由模式为例子投递消息
发送消息依然为跟上面一样
convertAndSend方法的参数:
第一个:交换机名
第二个:key名
第三个:发送的消息
rabbitTemplate.convertAndSend("test_exchange_confirm", "confirm", "message confirm....");
添加两个方法为投递返回的结果
Confirm 模式
@Test
public void testConfirm() {
rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
//correlationData 相关配置信息, ack exchange交换机 是否成功收到了消息。true 成功,false代表失败,cause 失败原因
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
System.out.println("confirm方法被执行了....");
if (ack) {
System.out.println("接收成功消息" + cause);
} else {
System.out.println("接收失败消息" + cause);
//做一些处理,让消息再次发送。
}
}
});
//进行消息发送
rabbitTemplate.convertAndSend("test_exchange_confirm","confirm","message Confirm...");
//进行睡眠操作,否则消息还没返回程序就结束了
try {
Thread.sleep(5000);
} catch (Exception e) {
e.printStackTrace();
}
}
return模式
@Test
public void testReturn() {
//设置交换机处理失败消息的模式 为true的时候,消息达到不了 队列时,会将消息重新返回给生产者
rabbitTemplate.setMandatory(true);
//定义回调
rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
//message 消息,replyCode 错误码,replyText 错误信息,exchange 交换机,routingKey 路由key
@Override
public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
System.out.println("return 执行了....");
System.out.println("message:"+message);
System.out.println("replyCode:"+replyCode);
System.out.println("replyText:"+replyText);
System.out.println("exchange:"+exchange);
System.out.println("routingKey:"+routingKey);
//处理
}
});
//进行消息发送
rabbitTemplate.convertAndSend("test_exchange_confirm","confirm","message return...");
//进行睡眠操作
try {
Thread.sleep(5000);
} catch (Exception e) {
e.printStackTrace();
}
}