从源码层级深入探索 Spring AMQP 如何在 Spring Boot 中实现 RabbitMQ 集成——消费者如何进行消费

本章节主要从底层源码探索Spring Boot中RabbitMQ如何进行消费,至于RabbitMQ是如何使用如何生产消息,本章不做过多介绍,感兴趣的小伙伴可以参考:从源码层级深入探索 Spring AMQP 如何在 Spring Boot 中实现 RabbitMQ 集成------生产者如何将消息发送到 RabbitMQ Exchange-CSDN博客文章浏览阅读14次。RabbitAutoConfiguration,RabbitAdmin,RabbitTemplate,declareExchanges,convertAndSendhttps://blog.csdn.net/qq_26733517/article/details/144511012?spm=1001.2014.3001.5501

1.Spring Boot中RabbitMQ如何消费

Spring Boot中RabbitMQ的消费使用非常简单,一般使用@RabbitListener或者@RabbitListener+@RabbitHandler,前者使用在方法上, 一个消费者只有一个方法,消息来了就是目标方法执行,不管参数类型跟消息类型是否匹配。后者使用在类上,一个消费者包含多个候选处理方法,根据消息的类型进行选择执行。具体使用如下图:

那么为什么使用一个简单的注解@RabbitListener就可以实现消费呢,它的底层是如何运转实现的呢?

2.@RabbitListener注解底层如何实现消费的

其是这还是离不开Spring Boot自动装配引入的RabbitAutoConfiguration配置类,再该类中帮我们引入了一系列配置类,如下:RabbitAutoConfiguration->RabbitAnnotationDrivenConfiguration->EnableRabbitConfiguration(该配置类中某个bean对象存在@EnableRabbit注解)->

RabbitListenerConfigurationSelector(@EnableRabbit注解引入)->RabbitBootstrapConfiguration->

RabbitListenerAnnotationBeanPostProcessor、RabbitListenerEndpointRegistry。消费实现的核心就是这两个配置类,接下来我们进行逐一研究。

1.RabbitListenerAnnotationBeanPostProcessor

该配置类实现了BeanPostProcessor+SmartInitializingSingleton接口,再所有的bean对象初始化前后均会调用BeanPostProcessor接口的前置、后置方法。再所有的bean对象初始化完成后(所有的bean对象已经生成)会调用SmartInitializingSingleton接口的afterSingletonsInstantiated方法。其主要作用是用来解析@RabbitListener,具体如下:

接着分别看一下processAmqpListener和processMultiMethodListeners两个方法,如下图:

从上面两个图中可以看出,二者底层均是调用了processListener方法,该方法具体如下:

接着看一下registerEndpoint方法,如下:

至此整个BeanPostProcessor接口的后置方法就已经完成,其作用就是将解析的@RabbitListener注解的信息封装成一个个AmqpListenerEndpointDescriptor里面封装了AbstractRabbitListenerEndpoint,然后放入到了RabbitListenerEndpointRegistrar.endpointDescriptors属性集合中。

执行完BeanPostProcessor接口后,等ioc容器的所有bean对象初始化完成后会继续调用该方法的afterSingletonsInstantiated方法,具体如下:

接着看一下this.registrar.afterPropertiesSet()方法,具体如下:

接着看一下registerListenerContainer方法,具体如下:

至此SmartInitializingSingleton接口的方法afterSingletonsInstantiated,将每一个@RabbitListener注解的信息封装成了SimpleMessageListenerContainer,然后封装到了RabbitListenerEndpointRegistry中的listenerContainers属性集合中,该类是不是有点眼熟,就是我们开始时说的两个核心类之一,接下来我们便研究一下它。

2.RabbitListenerEndpointRegistry

RabbitListenerEndpointRegistry实现了lifecyle接口,再spring容器刷新的最后一步会调用该类的start方法,处理上面解析的@RabbitListener注解信息,具体如下:

接着看一下startIfNecessary方法,调用每一个MessageListenerContainer(SimpleMessageListenerContainer)的start方法,如下:

调用的为AbstractMessageListenerContainer(父类)中的start方法,如下:

紧接着看一下SimpleMessageListenerContainer中的doStart()方法,如下:

接着看一下AsyncMessageProcessingConsumer的run() ,如下:

初始化的过程此处就不再介绍了,主要看一下事件如何处理的,即mainLoop方法,具体如下:

receiveAndExecute方法底层调用了doReceiveAndExecute方法,具体如下:

目标方法的执行涉及的东西比较多,包括处理在@RabbitListener注解中使用errorHandler和returnExceptions等属性,比较复杂,本篇暂不做过多介绍。我们看一下Spring Boot的假的'自动确认'吧,即commitIfNecessary方法,如下:

所以说Spring Boot提供所谓自动确认并不是真正的自动确认,只是Spring Boot再执行完目标方法后帮我们进行了确认,所以对开发者来说感知上是自动确认。

如果您希望更深入地学习SpringBoot源码,我强烈推荐您访问以下项目链接:https://gitee.com/chengyadong555/spring-boot.git。在这个项目中,您将发现对SpringBoot源码的逐行分析,作者不仅提供了丰富的注释,还融入了自己独到的理解和见解。

相关推荐
霸道流氓气质11 分钟前
Spring AI 结构化输出 Agent 实战:让大模型返回精准 JSON
人工智能·spring·json
段ヤシ.38 分钟前
回顾Java知识点,面试题汇总Day10(持续更新)
java·开发语言·spring
hikktn1 小时前
企业级Spring Boot应用管理:从零打造生产级启动脚本
java·spring boot·后端
霸道流氓气质1 小时前
Spring Boot + MyBatis-Plus 实现异常隔离的 Upsert 数据落库(含远程调用数据补全)
spring boot·后端·mybatis
不懂的浪漫1 小时前
01|从 Spring Boot 项目理解 RAG:ingest、query、rerank、trace 到 eval
java·人工智能·spring boot·后端·ai·rag
__log2 小时前
NestJS vs Spring Boot:从架构哲学到实战选择的技术全景解析
spring boot·后端·架构·typescript
拽着尾巴的鱼儿2 小时前
国密算法 Spring Boot 实战:SM2/SM3/SM4 完整集成指南
spring boot·后端·算法
Devin~Y2 小时前
大厂Java面试实战:Spring Boot微服务、Redis缓存、Kafka消息队列与Spring AI RAG
java·spring boot·redis·kafka·mybatis·spring mvc·hikaricp
小江的记录本2 小时前
【Java基础】集合框架: ArrayList vs LinkedList 核心区别、扩容机制(附《思维导图》+《面试高频考点清单》)
java·数据库·python·mysql·spring·面试·maven
夕除2 小时前
spring boot 10
java·python·spring