【RabbitMQ】RabbitMQ整合Spring和SpringBoot

本文详细介绍了如何将RabbitMQ整合到Spring和SpringBoot应用中,从依赖配置、生产者和消费者设置,到消息发送和监听的实现,涵盖了fanout、direct、topic三种交换机类型。

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

在已经大致了解了RabbitMQ的消息模式的基础上,可以研究RabbitMQ如何整合Spring和SpringBoot

1、RabbitMQ整合Spring

1.1、依赖

Spring整合RabbitMQ的依赖有两个,一个是spring-context,一个是spring-rabbit

<dependencies>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context</artifactId>
		<version>5.2.1.RELEASE</version>
	</dependency>
	<dependency>
		<groupId>org.springframework.amqp</groupId>
		<artifactId>spring-rabbit</artifactId>
		<version>2.1.5.RELEASE</version>
	</dependency>
</dependencies>

1.2、编写RabbitMQ的配置文件

在配置文件中,配置rabbitmq-server的相关信息,包括host、port、username、password、virtualhosts。

rabbitmq.host: 192.168.127.131
rabbitmq.port: 5672
rabbitmq.username: admin
rabbitmq.password: 123456
rabbitmq.virtual-host: /

1.3、Producer

1.3.1、编写Spring的配置文件

在Spring配置文件中,将连接工厂、队列、交换机都托管到Spring容器中。
(1)创建连接工厂

<!-- 创建连接工程 -->
<context:property-placeholder location="classpath:rabbitmq.yaml"/>
    <rabbit:connection-factory id="connectionFactory" host="${rabbitmq.host}" port="${rabbitmq.port}"
                               username="${rabbitmq.username}" password="${rabbitmq.password}"
                               virtual-host="${rabbitmq.virtual-host}"
/>
<rabbit:admin connection-factory="connectionFactory"/>

(2)声明队列

<rabbit:queue id="队列类名" name="队列名称" auto-declare="true"/>

示例:

<rabbit:queue id="spring_fanout_queue_1" name="spring_fanout_queue_1" auto-declare="true"/>

(3)声明交换机,绑定交换机和队列

  • fanout交换机:
<rabbit:交换机类型 id="交换机id" name="交换机名字" auto-declare="true">
    <rabbit:bindings>
    	<rabbit:binding queue="绑定的队列名"/>
    </rabbit:bindings>
</rabbit:fanout-exchange>
  • direct交换机
<rabbit:交换机类型 id="交换机id" name="交换机名字" auto-declare="true">
    <rabbit:bindings>
    	<rabbit:binding queue="绑定的队列名" key="路由"/>
    </rabbit:bindings>
</rabbit:fanout-exchange>
  • topic交换机
<rabbit:交换机类型 id="交换机id" name="交换机名字" auto-declare="true">
    <rabbit:bindings>
    	<rabbit:binding queue="绑定的队列名" pattern="路由pattern"/>
    </rabbit:bindings>
</rabbit:fanout-exchange>

示例:

<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>
        <rabbit:binding queue="spring_fanout_queue_2"></rabbit:binding>
    </rabbit:bindings>
</rabbit:fanout-exchange>

(4)创建template
最后别忘了创建rabbitmq template,用于发送消息

<rabbit:template id="rabbitTemplate" connection-factory="connectionFactory"/>

完整版(以topic交换机为例):

<?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:rabbit="http://www.springframework.org/schema/rabbit"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/rabbit
        http://www.springframework.org/schema/rabbit/spring-rabbit.xsd">
        <!-- 创建连接工程 -->
    <context:property-placeholder location="classpath:rabbitmq.yaml"/>
    <rabbit:connection-factory id="connectionFactory" host="${rabbitmq.host}" port="${rabbitmq.port}"
                               username="${rabbitmq.username}" password="${rabbitmq.password}"
                               virtual-host="${rabbitmq.virtual-host}"
    />

    <rabbit:admin connection-factory="connectionFactory"/>
	 <!-- topic模式 -->
    <rabbit:queue id="spring_topic_queue_all" name="spring_topic_queue_all" auto-declare="true"></rabbit:queue>
    <rabbit:queue id="spring_topic_queue_insert" name="spring_topic_queue_insert" auto-declare="true"></rabbit:queue>
    <rabbit:queue id="spring_topic_queue_update" name="spring_topic_queue_update" auto-declare="true"></rabbit:queue>
    <rabbit:topic-exchange id="spring_topic_exchange" name="spring_topic_exchange" auto-declare="true">
        <rabbit:bindings>
            <rabbit:binding pattern="test.*" queue="spring_topic_queue_all"></rabbit:binding>
            <rabbit:binding pattern="#.insert" queue="spring_topic_queue_insert"></rabbit:binding>
            <rabbit:binding pattern="*.update" queue="spring_topic_queue_update"></rabbit:binding>
        </rabbit:bindings>
    </rabbit:topic-exchange>
    <!--定义rabbitTemplate对象操作可以在代码中方便发送消息-->
    <rabbit:template id="rabbitTemplate" connection-factory="connectionFactory"/>
</beans>

1.3.2、发送消息

spring配置文件完成后,producer就可以发送消息到交换机了。

public class Start {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("spring-rabbitmq.xml");
        RabbitTemplate rabbitTemplate = ac.getBean("rabbitTemplate",RabbitTemplate.class);              
        rabbitTemplate.convertAndSend("spring_topic_exchange","test.all","topic模式,发给all的");
        rabbitTemplate.convertAndSend("spring_topic_exchange","test.insert","topic模式,发给all和insert的");
        rabbitTemplate.convertAndSend("spring_topic_exchange","test.update","topic模式,发给all和update的");
    }
}

1.4、Consumer

(1)创建连接工厂

    <!-- 创建连接工程 -->
    <context:property-placeholder location="classpath:rabbitmq.yaml"/>
    <rabbit:connection-factory id="connectionFactory" host="${rabbitmq.host}" port="${rabbitmq.port}"
                               username="${rabbitmq.username}" password="${rabbitmq.password}"
                               virtual-host="${rabbitmq.virtual-host}"/>

    <rabbit:admin connection-factory="connectionFactory"/>

(2)配置监听器
在Spring中,Consumer是通过监听器来监听队列的消息的。监听器要实现 MessageListener 接口,并且重写 onMessage 方法。

示例:

public class TopicListener01 implements MessageListener {
    @Override
    public void onMessage(Message message) {
        try {
            String msg = new String(message.getBody(),"utf-8");
            System.out.printf("监听器:%s,交换机:%s, 队列:%s, 路由key:%s, 消息:%s\n",
                    "TopicListener01",
                    message.getMessageProperties().getReceivedExchange(),
                    message.getMessageProperties().getConsumerQueue(),
                    message.getMessageProperties().getReceivedRoutingKey(),
                    msg);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }
}

(3)Spring配置文件中绑定队列和监听器

<bean id="xx" class="xx"/>
<rabbit:listener-container connection-factory="connectionFactory" auto-declare="true">
    <rabbit:listener ref="监听器名" queuenames="队列名"/>
    <rabbit:listener ref="监听器名" queuenames="队列名"/>
    ...
</rabbit:listener-container>

示例:

<bean id="TopicListener01" class="com.wxf.listener.TopicListener01"/>
<rabbit:listener-container connection-factory="connectionFactory" auto-declare="true">
	<rabbit:listener ref="TopicListener01" queue-names="spring_topic_queue_all"/>
</rabbit:listener-container>

完整版:

<?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:rabbit="http://www.springframework.org/schema/rabbit"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/rabbit
        http://www.springframework.org/schema/rabbit/spring-rabbit.xsd">
        <bean id="TopicListener01" class="com.wxf.listener.TopicListener01"/>
        <rabbit:listener-container connection-factory="connectionFactory" auto-declare="true">
        	<rabbit:listener ref="TopicListener01" queue-names="spring_topic_queue_all"/>
        </rabbit:listener-container>
</beans>

最后在consumer的测试方法中写个 while(true){} 就可以让Consumer一直监听队列,获取消息啦。

2、RabbitMQ整合SpringBoot

RabbitMQ整合SpringBoot也非常快,和Spring也非常像,只是用注解简化了开发。

2.1、依赖

springboot和rabbitmq的相关依赖是 spring-boot-starter-amqp

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-amqp</artifactId>
	<version>2.1.4.RELEASE</version>
</dependency>

2.2、rabbitMQ相关配置

同样在springboot的application.yaml中配置rabbitMQ的host、port、username、password、virtualhost信息。

spring:
  rabbitmq:
    host: 192.168.127.131
    port: 5672
    username: admin
    password: 123456
    virtual-host: /

2.3、Producer

2.3.1、配置类

在配置类里声明和绑定队列和交换机。
(1)声明交换机

交换机用 ExchangeBuilder 声明。其中:

fanout交换机的声明方法是

ExchangeBuilder.fanoutExchange(交换机名).durable(true).build();

direct交换机的声明方法是

ExchangeBuilder.directExchange(交换机名).durable(true).build();

topic交换机的声明方法是

ExchangeBuilder.topicExchange(交换机名).durable(true).build();

示例:

@Bean
public Exchange fanoutExchange(){
	return ExchangeBuilder.fanoutExchange(FANOUT_EXCHANGE).durable(true).build();
}
@Bean
public Exchange directExchange(){
	return ExchangeBuilder.directExchange(DIRECT_EXCHANGE).durable(true).build();
}
@Bean
public Exchange topicExchange(){
	return ExchangeBuilder.topicExchange(TOPIC_EXCHANGE).durable(true).build();
}

(2)声明队列

@Bean
public Queue topicQueueAll(){
	return QueueBuilder.durable("队列名称").build();
}

示例:

@Bean
public Queue topicQueueAll(){
	return QueueBuilder.durable("spring_topic_queue_all").build();
}

(3) 绑定队列和交换机

@Bean
public Binding topicExchangeAll(@Qualifier("声明队列方法名")Queue queue,
                                @Qualifier("声明交换机方法名") Exchange exchange){
	return BindingBuilder.bind(queue).to(exchange).with("路由").noargs();
}

示例:

 @Bean
public Binding topicExchangeAll(@Qualifier("topicQueueAll")Queue queue,
                                @Qualifier("topicExchange") Exchange exchange){
	return BindingBuilder.bind(queue).to(exchange).with("test.*").noargs();
}

完整版:

@Configuration
public class ProducerConfig {
	public static final String TOPIC_EXCHANGE = "springboot_topic-exchange";
	public static final String TOPIC_QUEUE_ALL = "springboot_topic_queue_all";
    public static final String TOPIC_QUEUE_INSERT = "springboot_topic_queue_insert";
	@Bean
	public Exchange topicExchange(){
		return ExchangeBuilder.topicExchange(TOPIC_EXCHANGE).durable(true).build();
	}
	@Bean
    public Queue directQueueUpdate(){
        return QueueBuilder.durable(DIRECT_QUEUE_UPDATE).build();
    }
    @Bean
    public Queue topicQueueInsert(){
        return QueueBuilder.durable(TOPIC_QUEUE_INSERT).build();
    }
     @Bean
    public Binding topicExchangeInsert(@Qualifier("topicQueueInsert")Queue queue,
                                       @Qualifier("topicExchange") Exchange exchange){
        return BindingBuilder.bind(queue).to(exchange).with("#.insert").noargs();
    }
    @Bean
    public Binding topicExchangeAll(@Qualifier("topicQueueAll")Queue queue,
                                    @Qualifier("topicExchange") Exchange exchange){
        return BindingBuilder.bind(queue).to(exchange).with("test.*").noargs();
    }
}

2.3.2、发送消息

注入 RabbitTemplate ,用 convertAndSend 方法发送消息。

@SpringBootTest(classes = Start.class)
@RunWith(SpringRunner.class)
public class Test {
    @Resource
    private RabbitTemplate rabbitTemplate;

    @org.junit.Test
    public void test01(){
      rabbitTemplate.convertAndSend(ProducerConfig.TOPIC_EXCHANGE,"test.insert","发送给topic:insert和all");     
      rabbitTemplate.convertAndSend(ProducerConfig.TOPIC_EXCHANGE,"test.all","发送给topic:all");
    }
}

2.4、Consumer

2.4.1、配置监听器

@RabbitListener 绑定监听器和队列。

@Component
public class MyListener {
    @RabbitListener(queues = "springboot_topic_queue_insert")
    public void myListener5(String message){
        System.out.println("消费者接收到的消息为:" + message);
    }
    @RabbitListener(queues = "springboot_topic_queue_all")
    public void myListener6(String message){
        System.out.println("消费者接收到的消息为:" + message);
    }
}

2.4.2、测试

在测试类中注入 RabbitTemplate ,然后同样写个 while(true){} 就可以一直监听队列的消息了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值