? 本章節主要從底層源碼探索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源碼的逐行分析,作者不僅提供了豐富的注釋,還融入了自己獨到的理解和見解。