Spring整合RabbitMQ-配制文件方式-1-消息生产者

Spring-amqp是对AMQP的一些概念的一些抽象,Spring-rabbit是对RabbitMQ操作的封装实现。

主要有几个核心类RabbitAdminRabbitTemplateSimpleMessageListenerContainer

RabbitAdmin类完成对Exchange、Queue、Binding的操作,在容器中管理 了RabbitAdmin类的时候,可以对Exchange、Queue、Binding进行自动声明。

RabbitTemplate类是发送和接收消息的工具类。

SimpleMessageListenerContainer是消费消息的容器。

目前一些比较新的项目会使用基于注解的方式,而比较老的一些项目可能还是基于配制文件的方式。

此处使用的Spring依赖为:

xml 复制代码
            <dependency>
                <groupId>org.springframework.amqp</groupId>
                <artifactId>spring-rabbit</artifactId>
                <version>2.2.7.RELEASE</version>
            </dependency>

消息的生产者

java 复制代码
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.core.MessagePropertiesBuilder;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Product {

    public static void main(String[] args) throws Exception {
        AbstractApplicationContext context = new ClassPathXmlApplicationContext("spring-rabbit.xml");


        RabbitTemplate template = context.getBean(RabbitTemplate.class);


        MessagePropertiesBuilder propertiesBuilder = MessagePropertiesBuilder.newInstance();
        propertiesBuilder.setContentEncoding("gbk");
        propertiesBuilder.setContentType(MessageProperties.CONTENT_TYPE_TEXT_PLAIN);


        Message msg = MessageBuilder.withBody("hello world".getBytes("gbk"))
                .andProperties(propertiesBuilder.build()).build();

        template.convertAndSend("ex.direct", "routing.q1", msg);


        context.close();
    }
}

spring-rabbit.xml

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: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/rabbit
    http://www.springframework.org/schema/rabbit/spring-rabbit.xsd">

    <!--配制连接工厂-->
    <rabbit:connection-factory id="connectFactory"
                               host="node1" virtual-host="/"
                               username="root" password="123456"
                               port="5672"
    ></rabbit:connection-factory>


    <!--用于自动向RabbitMQ声明队列、交换器、绑定 等操作工具类-->
    <rabbit:admin id="rabbitAdmin" connection-factory="connectFactory"></rabbit:admin>


    <!--用于简化操作的模板类-->
    <rabbit:template connection-factory="connectFactory" id="rabbitTemplate" />


    <!--声明队列队列-->
    <rabbit:queue id="msg1" name="queue.msg" durable="false" exclusive="false" auto-delete="false" ></rabbit:queue>

    <!--声明交换器-->
    <rabbit:direct-exchange name="ex.direct" durable="false" auto-delete="false" id="directExchange" >
        <rabbit:bindings>
            <!--key表示绑定键-->
            <!--queue表示将交换器绑定到哪个消息队列,使用队列换id,不要使用Bean的name-->
            <!--exchange表示交接交换器绑定到哪个交换器。-->
            <rabbit:binding queue="msg1" key="routing.q1" ></rabbit:binding>
        </rabbit:bindings>
    </rabbit:direct-exchange>


</beans>

运行生产者的代码,便可查看数据已经发送成功

sh 复制代码
[root@nullnull-os ~]# rabbitmqctl list_exchanges --formatter pretty_table
Listing exchanges for vhost / ...
┌────────────────────┬─────────┐
│ name               │ type    │
├────────────────────┼─────────┤
│ amq.fanout         │ fanout  │
├────────────────────┼─────────┤
│ ex.busi.topic      │ topic   │
├────────────────────┼─────────┤
│ amq.rabbitmq.trace │ topic   │
├────────────────────┼─────────┤
│ amq.headers        │ headers │
├────────────────────┼─────────┤
│ amq.topic          │ topic   │
├────────────────────┼─────────┤
│ amq.direct         │ direct  │
├────────────────────┼─────────┤
│ ex.direct          │ direct  │
├────────────────────┼─────────┤
│                    │ direct  │
├────────────────────┼─────────┤
│ ex.routing         │ direct  │
├────────────────────┼─────────┤
│ amq.match          │ headers │
└────────────────────┴─────────┘
[root@nullnull-os ~]# rabbitmqctl list_bindings --formatter pretty_table
Listing bindings for vhost /...
┌─────────────┬─────────────┬──────────────────┬──────────────────┬─────────────┬───────────┐
│ source_name │ source_kind │ destination_name │ destination_kind │ routing_key │ arguments │
├─────────────┼─────────────┼──────────────────┼──────────────────┼─────────────┼───────────┤
│             │ exchange    │ queue.msg        │ queue            │ queue.msg   │           │
├─────────────┼─────────────┼──────────────────┼──────────────────┼─────────────┼───────────┤
│ ex.direct   │ exchange    │ queue.msg        │ queue            │ routing.q1  │           │
└─────────────┴─────────────┴──────────────────┴──────────────────┴─────────────┴───────────┘
[root@nullnull-os ~]# rabbitmqctl list_queues --formatter pretty_table
Timeout: 60.0 seconds ...
Listing queues for vhost / ...
┌───────────┬──────────┐
│ name      │ messages │
├───────────┼──────────┤
│ queue.msg │ 1        │
└───────────┴──────────┘
[root@nullnull-os ~]# 

可以观察到数据已经成功的发送了。

遇到的问题:

java 复制代码
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.amqp.rabbit.config.BindingFactoryBean#0': Cannot resolve reference to bean 'queue.msg' while setting bean property 'destinationQueue'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'queue.msg' available
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:342)
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:113)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1699)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1444)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:876)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:144)
	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:85)
	at com.nullnull.learn.Product.main(Product.java:18)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'queue.msg' available
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:814)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1282)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:297)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
	at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:330)
	... 15 more

问题原因:

xml 复制代码
    <rabbit:direct-exchange name="ex.direct" durable="false" auto-delete="false" id="directExchange" >
        <rabbit:bindings>
            <rabbit:binding queue="queue.msg" key="routing.q1" ></rabbit:binding>
        </rabbit:bindings>
    </rabbit:direct-exchange>

此处要配制的是队列的id,而不是队列的名称。

修改后:

xml 复制代码
 <!--声明交换器-->
    <rabbit:direct-exchange name="ex.direct" durable="false" auto-delete="false" id="directExchange" >
        <rabbit:bindings>
            <!--key表示绑定键-->
            <!--queue表示将交换器绑定到哪个消息队列,使用队列换id,不要使用Bean的name-->
            <!--exchange表示交接交换器绑定到哪个交换器。-->
            <rabbit:binding queue="msg1" key="routing.q1" ></rabbit:binding>
        </rabbit:bindings>
    </rabbit:direct-exchange>
相关推荐
Bs_MoneyMagnet4 小时前
基于springboot+vue的心理咨询预约与随访平台的设计与实现 源码+文档
vue.js·spring boot·后端·spring·毕业设计·旅游·计算机毕业设计
吃饱了得干活6 小时前
RabbitMQ 原理解析(下):存储、集群与可靠投递
后端·rabbitmq
步行cgn10 小时前
Spring 底层如何创建对象:反射机制与实例化策略
java·后端·spring
步行cgn12 小时前
Spring 注入 null 和空字符串详解
数据库·spring·oracle
Wang's Blog13 小时前
Java框架快速入门: Spring Security+OAuth2之单点登录(SSO)实战
服务器·spring·状态模式
譕痕13 小时前
Idea 集成 智能体开发工具“千问(qwen)”
java·ide·spring·语言模型
步行cgn14 小时前
Spring 注入内部 Bean 详解
java·spring·rpc
前端初见15 小时前
Java+AI零基础入门到大牛
java·spring boot·spring·java-ee·intellij-idea
天天喝旺仔15 小时前
深入理解 JWT:从 Token 结构、签名机制到前后端鉴权实战
redis·安全·spring·微服务·https
QQ_216962909616 小时前
基于SpringBoot+Vue的小生活平台的设计与实现
java·数据库·vue.js·spring boot·spring·微信小程序·生活