RabbitMQ的Java应用(2) -- 使用Spring AMQP开发消费者应用

本文详细介绍了如何使用Spring AMQP连接RabbitMQ并开发消费者应用,包括消费者应用程序框架搭建、消费者Tag自定义、消息手动确认模式、RPC模式设置、消费者并发数与预取数设置等内容,并探讨了RabbitMQ的Channel和Connection缓存以及Spring AMQP的重连机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前一篇中我们介绍了使用RabbitMQ Java Client访问RabbitMQ的方法。但是使用这种方式访问RabbitMQ,开发者在程序中需要自己管理Connection,Channel对象,Consumer对象的创建,销毁,这样会非常不方便。我们下面介绍使用Spring AMQP连接RabbitMQ,进行消息的接收和发送。

Spring AMQP是一个Spring子项目,它提供了访问基于AMQP协议的消息服务器的解决方案。它包含两部分,spring-ampq是基于AMQP协议的消息发送和接收的高层实现,spring-rabbit是基于RabbitMQ的具体实现。这两部分我们下面都会使用到。

Spring-AMQP中的基础类/接口

spring-amqp中定义了几个基础类/接口,Message,Exchange,Queue,Binding

Message

public class Message implements Serializable 
{
  private final MessageProperties messageProperties;
 
  private final byte[] body;

spring-amqp中的Message类类似于javax的Message类,封装了消息的Properties和消息体。

Exchange

spring-amqp定义了Exchange接口

public interface Exchange extends Declarable {
        //Exchange名称
	String getName();
        //Exchange的类型
	String getType();
        //Exchange是否持久化
	boolean isDurable();
        //Exchange不再被使用时(没有任何绑定的情况下),是否由RabbitMQ自动删除
	boolean isAutoDelete();
        //Exchange相关的参数
	Map<String, Object> getArguments();


这个接口和RabbitMQ Client中的Exchange类相似。 spring-amqp中的Exchange继承关系如下图所示


AbstractExchange类是所有Exchange类的父类,实现Exchange接口的具体方法。 CustomExchange针对用户自定义的Exchange对象。其他四个Exchange类,分别对应四种Exchange。 我们在Spring配置文件中配置Exchange对象时,使用的就是这几种Exchange类。

Queue

spring-amqp定义了Queue类,和RabbitMQ Client中的Queue相似,对应RabbitMQ中的消息队列。

public class Queue extends AbstractDeclarable {
 
	private final String name;
 
	private final boolean durable;
 
	private final boolean exclusive;
 
	private final boolean autoDelete;
 
	private final java.util.Map<java.lang.String, java.lang.Object> arguments;
 
        public Queue(String name, boolean durable, boolean exclusive, boolean autoDelete) {
		this(name, durable, exclusive, autoDelete, null);
	} 

Binding

Binding类是对RabbitMQ中Exchange-Exchange以及Exchange-Queue绑定关系的抽象。

public class Binding extends AbstractDeclarable 
{
 
	public enum DestinationType {
		QUEUE, EXCHANGE;
	}
 
	private final String destination;
 
	private final String exchange;
 
	private final String routingKey;
 
	private final Map<String, Object> arguments;
 
	private final DestinationType destinationType;
 
	public Binding(String destination, DestinationType destinationType, String exchange, String routingKey,
			Map<String, Object> arguments) {
		this.destination = destination;
		this.destinationType = destinationType;
		this.exchange = exchange;
		this.routingKey = routingKey;
		this.arguments = arguments;
	}

对照RabbitMQ Java Client中Channel接口的queueBind和ExchangeBind方法

Exchange.BindOk exchangeBind(String destination, String source, String routingKey, Map<String, Object> arguments) 
 
Queue.BindOk queueBind(String queue, String exchange, String routingKey, Map<String, Object> arguments)

我们可以看出Binding类实际是对底层建立的Exchange-Queue和Exchange-Exchange绑定关系的高层抽象记录类,它使用枚举类型DestinationType区分Exchange-Queue和Exchange-Exchange两种绑定。

Spring AMQP搭建消费者应用

消费者应用程序框架搭建

我们接下来使用spring-amqp搭建一个RabbitMQ的消费者Web应用,我们先创建一个maven webapp应用程序,再添加一个dependency。

<dependency>
    <groupId>org.springframework.amqp</groupId>
    <artifactId>spring-rabbit</artifactId>
    <version>1.6.5.RELEASE</version>
 </dependency> 

spring-rabbit库的引入是为了使用它里面的RabbitAdmin类,创建Exchange,Queue和Binding对象,在导入这个库的时候同时引入了 spring-ampq和rabbitmq-client的库,不需要另行导入。

在src/main/resources目录下创建application.properties文件,用于记录RabbitMQ的配置信息。

mq.ip=localhost
mq.port=5672
mq.userName=rabbitmq_consumer
mq.password=123456
mq.virutalHost=test_vhosts
在src/main/resource目录下创建applicationContext.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
 
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="
		 http://www.springframework.org/schema/beans
		 http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
		 http://www.springframework.org/schema/util
		 http://www.springframework.org/schema/util/spring-util-4.0.xsd
   		 http://www.springframework.org/schema/context
   		 http://www.springframework.org/schema/context/spring-context-4.0.xsd" >
 
    <context:annotation-config/>
 
    <context:property-placeholder
            ignore-unresolvable="true" location="classpath*:/application.properties" />
 
    <!--从RabbitMQ Java Client创建RabbitMQ连接工厂对象-->
    <bean id="rabbitMQConnectionFactory" class="com.rabbitmq.client.ConnectionFactory">
        <property name="username" value="${mq.userName}" />
        <property name="password" value="${mq.password}" />
        <property name="host" value="${mq.ip}" />
        <property name="port" value="${mq.port}" />
        <property name="virtualHost" value="${mq.virutalHost}" />
    </bean>
 
    <!--基于RabbitMQ连接工厂对象构建spring-rabbit的连接工厂对象Wrapper-->
    <bean id="connectionFactory" class="org.springframework.amqp.rabbit.connection.CachingConnectionFactory">
     	<constructor-arg name="rabbitConnectionFactory" ref="rabbitMQConnectionFactory" />
    </bean>
 
    <!--构建RabbitAmdin对象,它负责创建Queue/Exchange/Bind对象-->
    <bean id="rabbitAdmin" class="org.springframework.amqp.rabbit.core.RabbitAdmin">
        <constructor-arg name="connectionFactory" ref="connectionFactory" />
        <property name="autoStartup" value="true"></property>
    </bean>
 
    <!--构建Rabbit Template对象,用于发送RabbitMQ消息,本程序使用它发送返回消息-->
    <bean id="rabbitTemplate" class="org.springframework.amqp.rabbit.core.RabbitTemplate">
        <constructor-arg name="connectionFactory" ref="connectionFactory" />
    </bean>
 
    <!--RabbitMQ消息转化器,用于将RabbitMQ消息转换为AMQP消息,我们这里使用基本的Message Converter -->
    <bean id="serializerMessageConverter"
          class="org.springframework.amqp.support.converter.SimpleMessageConverter" />
 
    <!--Message Properties转换器,用于在spring-amqp Message对象中的Message Properties和RabbitMQ的
     Message Properties对象之间互相转换 -->      
    <bean id="messagePropertiesConverter"
          class="org.springframework.amqp.rabbit.support.DefaultMessagePropertiesConverter" />      
 
    <!--定义AMQP Queue-->
    <bean id="springMessageQueue" class="org.springframework.amqp.core.Queue">
        <constructor-arg name="name" value="springMessageQueue" />
        <constructor-arg name="autoDelete" value="false" />
        <constructor-arg name="durable" value="true" />
        <constructor-arg name="exclusive" value="false" />
        <!--定义AMQP Queue创建所需的RabbitAdmin对象-->
        <property name="adminsThatShouldDeclare" ref="rabbitAdmin" />
        <!--判断是否需要在连接RabbitMQ后创建Queue-->
        <property name="shouldDeclare" value="true" />
    </bean>
 
    <!--定义AMQP Exchange-->
    <bean id="springMessageExchange" class="org.springframework.amqp.core.DirectExchange">
        <constructor-arg name="name" value="springMessageExchange" />
        <constructor-arg name="durable" value="true" />
        <constructor-arg name="autoDelete" value="false" />
        <!--定义AMQP Queue创建所需的RabbitAdmin对象-->
        <property name="adminsThatShouldDeclare" ref="rabbitAdmin" />
        <!--判断是否需要在连接RabbitMQ后创建Exchange-->
        <property name="shouldDeclare" value="true" />
    </bean>
 
    <util:map id="emptyMap" map-class="java.util.HashMap" />
 
    <!--创建Exchange和Queue之间的Bind-->
    <bean id="springMessageBind" class="org.springframework.amqp.core.Binding">
        <constructor-arg name="destination" value="springMessageQueue" />
        <constructor-arg name="destinationType" value="QUEUE" />
        <constructor-arg name="exchange" value="springMessageExchange" />
        <constructor-arg name="routingKey" value="springMessage" />
        <constructor-arg name="arguments" ref="emptyMap" />
    </bean>
 
    <!--侦听springMessageQueue队列消息的Message Listener-->
    <bean id="consumerListener" 
    	class="com.qf.rabbitmq.listener.RabbitMQConsumer" />
 
    <!--创建侦听springMessageQueue队列的Message Listener Container-->
    <bean id="messageListenerContainer"
          class="org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer">
        <property name="messageConverter" ref="serializerMessageConverter" />
        <property name="connectionFactory" ref="connectionFactory" />
        <property name="messageListener" ref="consumerListener" />
        <property name="queues" ref="springMessageQueue" />
        <!--设置消息确认方式为自动确认-->
        <property name="acknowledgeMode" value="AUTO" />
    </bean>
</beans>
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值