<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          SpringBoot消息源碼解析:JMS基礎(chǔ)自動(dòng)配置

          共 9618字,需瀏覽 20分鐘

           ·

          2022-04-25 07:51


          SpringBoot消息源碼解析

          Spring框架對(duì)消息系統(tǒng)的整合提供了廣泛的支持:從簡(jiǎn)單使用 Jms Template 的 JMS API,到可接收異步消息的完整基礎(chǔ)結(jié)構(gòu)。Spring AMQP 為“高級(jí)消息隊(duì)列協(xié)議”提供了類似的功能集。

          同時(shí),Spring Boot 也為 RabbitTemplate 和 Rabbit MQ 提供了自動(dòng)配置選項(xiàng)。Spring Boot通過(guò)自動(dòng)配置對(duì) ActiveMQ、RabbitMQ 和 Apache Kafka 提供了支持。本章重點(diǎn)講解 SpringBoot 對(duì) JMS 和 ActiveMQ 的自動(dòng)配置操作。

          JMS 基礎(chǔ)自動(dòng)配置

          JMS 的全稱是 Java Message Service,即 Java 消息服務(wù)。它主要用于在生產(chǎn)者和消費(fèi)者之間進(jìn)行消息傳遞。JMS 只是一個(gè)標(biāo)準(zhǔn), 在使用的時(shí)候需要有具體實(shí)現(xiàn),比如后面要講到的ActiveMQ。

          在 Spring Boot 中,通過(guò) JmsAutoConfiguration 自動(dòng)配置來(lái)完成 JMS 的基礎(chǔ)組件的初始化。

          像其他自動(dòng)配置-樣,在 ME TA-INF/spring.factories 中可以找到注冊(cè)的 JMS 自動(dòng)配置類。

          # Auto Configure
          org. springframework . boot . autoconfigure . jms . JmsAutoConfiguration



          JmsAutoConfiguration 的注解

          我們先從 JmsAutoConfiguration 的注解部分看起。

          @Configuration(proxyBeanMethods = false)
          @Conditional0nClass({ Message . class, JmsTemplate.class })
          @ConditionalOnBean(ConnectionFactory . class)
          @EnableConfigurationProperties (JmsProperties .class)
          @Import (JmsAnnotat ionDrivenConfiguration. class)
          public class JmsAutoConfiguration {
          }

          @ConditionalOnClass 注解指定需要滿足在 classpath 下存在javax.jms.Message 類和
          org.springframework.jms.core.Jms Template 類的條件才會(huì)進(jìn)行初始化。

          @ConditionalOnBean 注解指定需要在容器中存在
          javax.jms.ConnectionFactory 的 Bean 對(duì)象時(shí)才會(huì)被實(shí)例化。

          ConnectionFactory 接口提供了用于創(chuàng)建與 JMS 代理進(jìn)行交互的 javax.jms.Connection 的標(biāo)準(zhǔn)方法。Spring 需要 ConnectionFactory 來(lái) 與 JMS 一起使用,但是通常不需要編程人員直接使用它。

          那么,ConnectionFactory 的 Bean 是在什么時(shí)候被初始化的呢?以 ActiveMQ 為例,Active-MQ 的自動(dòng)配置會(huì)在 JmsAutoConfiguration 配置之前執(zhí)行,并在其內(nèi)部創(chuàng)建Connection-Factory 實(shí)現(xiàn)類的 Bean 對(duì)象。其他消息框架也與此類似,至于是如何初始化的,后面關(guān)于 ActiveMQ 的自動(dòng)配置的部分我們會(huì)進(jìn)行詳解。

          @
          EnableConfigurationProperties引入了JMS的配置屬性類 ,對(duì)應(yīng)的就 是 在application.properties 文件中配置的以“spring.jms”為前綴的屬性。

          @Import 引入了
          JmsAnnotationDrivenConfiguration 配置,該配置類主要用于 Spring4.1 注解驅(qū)動(dòng)的 JMS 的自動(dòng)配置。

          下面我們先看
          JmsAnnotationDrivenConfiguration 的注解部分和構(gòu)造方法的源代碼。

          @Configuration(proxyBeanMethods = false)
          @ConditionalOnClass (EnableJms .class)class JmsAnnotationDrivenConfiguration {
          private final objectProvider destinat ionResolver;
          private final objectProvider transactionManager J
          private final objectProvider messageConverter;
          private final JmsProperties properties;
          JmsAnnotationDrivenConfiguration(ObjectProvider dest
          ination-
          Resolver,
          ObjectProvider tr
          ansactionManager, 0bject-
          Provider messageConver
          ter,
          JmsProperties properties) {
          this . destinationResolver = destinationResolver;
          this. transactionManager = transactionManager;
          this . messageConverter = messageConverter;
          this. properties = properties;
          }
          }

          @Configuration 聲 明 該 類 也 是 配 置 類 , @ConditionalOnClass 表 示 類 路 徑 下 需 存 在EnableJms 類。其中 EnableJms 為一個(gè)注解類,@EnableJms 用于開(kāi)啟 JMS 注解,使@JmsListener 注解生效。

          在之前章節(jié)已經(jīng)講過(guò)
          JmsAnnotationDrivenConfiguration 的構(gòu)造方法中 ObjectProvider 的作用,這里看其泛型部分類。其中 JmsProperties 參數(shù)為 JMS 的配置,前面已經(jīng)提到過(guò),下 面我們重點(diǎn)看其他 3 個(gè)參數(shù)。

          DestinationResolver 用于解決 JMS 目標(biāo)的策略接口,被 Jms Template 用于將目標(biāo)名稱從簡(jiǎn)單的字符串解析為實(shí)際的 Destination 實(shí)現(xiàn)實(shí)例。JmsTemplate 實(shí)例使用的默認(rèn)Destina-tionResolver 實(shí)現(xiàn)
          DynamicDestinationResolver 類。

          該接口只有一個(gè)方法, 通過(guò)源代碼可以更清晰地看出它的功能。

          @FunctionalInterface
          public interface Dest inationResolver
          //將給定的目標(biāo)名稱解析為定位資源或作為動(dòng)態(tài)的 Destinat ion(返回 topic 或 queue)
          // Session: 為當(dāng)前 JMS 的 Session
          // destinat ionName:目標(biāo)名稱
          // pubSubDomain: true 表示 pub-sub 模式,false 表示 P2P 模式
          Destination resolveDestinationName (@Nullable Session session, String destina-tionName, boolean pubSubDomain) throws
          JMSException;
          }

          Jta TransactionManager 是
          PlatformTransactionManager 的實(shí)現(xiàn)類,它提供了 Spring 的JTA 事務(wù)管理,也可用于分布式事務(wù)的管理。關(guān)于事務(wù)相關(guān)的內(nèi)容,在此不進(jìn)行展開(kāi)。

          MessageConverter 是一個(gè)策略接口, 用于指定 Java 對(duì)象和 JMS 消息之間的轉(zhuǎn)換器。

          SimpleMessageConverter 作 為 其 簡(jiǎn) 單 的 默 認(rèn) 實(shí) 現(xiàn) , 能 夠 處 理 TextMessages 、BytesMessages、 MapMessages 和 ObjectMessages 之 間的消息轉(zhuǎn)換。

          public interface MessageConverter {
          //轉(zhuǎn)換 Java 對(duì)象到 JMS 消息
          Message toMessage(object
          object,
          Session
          session
          )
          throws
          JMSException,
          MessageConversionException
          ;
          //轉(zhuǎn) JMS 消息為 Java 對(duì)象
          Object fromMessage (Message message) throws JMSException, MessageConversio
          nException
          ;
          }

          通過(guò) MessageConverter 接口方法的定義也能夠看出它的核心功能就是進(jìn)行 Java 對(duì)象與JMS 消息之間的轉(zhuǎn)換。

          了解完構(gòu)法我們先看
          DefaultJmsListenerContainerFactoryConfigurer 的初始化,代碼如下。

          @Bean
          @ConditionalOnMissingBean
          DefaultJmsListenerContainerFactoryConfigurer jmsL istenerContainerFactoryCon
          rer() {
          DefaultJmsL istenerContainerF actoryConfigurer configurer = new DefaultJmsL
          is -
          tenerContainerFactoryConfigurer();
          configurer . setDestinationResolver(this . destinationResolver . getIfUnique
          ());
          configurer . setTransactionManager(this . transactionManager . getIfUnique());
          configurer . setMessageConverter(this . messageConverter . getIfUnique());
          configurer . setJmsProperties (this . properties);
          return configurer;
          }

          初始化操作就是創(chuàng)建一個(gè)
          DefaultJmsListenerContainerFactoryConfigurer 對(duì)象,然后將上面構(gòu)造方法傳入的參數(shù)設(shè)置到 DefaultJmsListenerContainerFactoryConfigurer 對(duì)象中。該類的作用是配置DefaultJmsListenerContainerFactory通過(guò)DefaultJmsListenerContainerFact-oryConfigurer 中的 configure 方法將構(gòu)造方法中的參數(shù)項(xiàng)賦值給 DefaultJmsListenerContainer-Factory.而 DefaultJmsListenerContainerFactory是個(gè) JmsListenerContainerFactory 實(shí)現(xiàn),

          用于構(gòu)建常規(guī)的 DefaultMessageL istenerContainer。對(duì)于大多數(shù)用戶,這是默認(rèn)設(shè)置,對(duì)于用于手動(dòng)構(gòu)建此類容器定義的用戶,這應(yīng)該是一個(gè)很好的過(guò)渡路徑。

          接下來(lái)便是
          DefaultJmsListenerContainerFactory 的初始化操作,代碼如下。

          @Bean
          @ConditionalOnSingleCandidate(Connect ionFactory. class)
          @ConditionalOnMissingBean(name
          = "jimsListenerContainerFactory")
          DefaultJmsListenerContainerFactory jmsListenerContainerFactory(
          DefaultJmsListenerContainerF actoryConfigurer configurer, ConnectionFactory
          connectionFactory)
          {
          DefaultImsListenerContainerFactory factory = new DefaultJmsL istenerContai
          nerFactory()
          ;
          configurer . configure(factory, connectionFactory);
          return factory;
          }

          當(dāng)存在唯一候選 ConnectionFactory 的 Bean 并且當(dāng) name 為
          jmsListenerContainer-Factory的 DefaultJmsListenerContainerFactory Bean 不存在時(shí),會(huì)執(zhí)行創(chuàng)建和初始化操作。其中創(chuàng)建就是直接 new-一個(gè)對(duì)象,而關(guān)于初始化操作,上面已經(jīng)提到了,通過(guò) DefaultJms-ListenerContainerFactoryConfigurer 的 configure 方法來(lái)對(duì) DefaultJmsListenerContainerFacto-ry 對(duì)應(yīng)的各項(xiàng)參數(shù)進(jìn)行賦值。


          JmsAnnotationDrivenConfiguration 剩余部分代碼定義了兩個(gè)內(nèi)部類,代碼如下。

          @Configuration(proxyBeanMethods = false)
          @EnableJms
          @ConditionalOnMissingBean(name = JmsL istenerConfigUtils.JMS_ LISTENER NNOTA
          TION_
          PROCESSOR_ BEAN NAME)
          static class EnableJmsConfiguration
          @Configuration(proxyBeanMethods
          = false)
          @Conditional0nJndi
          static class IndiConfiguration {
          @Bean
          @Conditiona lOnMissingBean(DestinationResolver. class)
          JndiDestinationResolver dest inationResolver()
          {
          JndiDestinationResolver resolver = new JndiDestinationResolver();resolver . setFallbackToDynamicDestination(true);
          return resolver;
          }
          }

          其 中 , 內(nèi) 部 類 EnableJmsConfiguration 的 實(shí) 現(xiàn) 為 空 , 主 要 作 用 是 根 據(jù) 條 件 來(lái) 使@EnableJms 注解生效生效條件是類
          org.springframework.jms.config.internalJmsListenerAnnotation-Processor 對(duì)應(yīng)的 Bean 不存在。

          內(nèi)部類 JndiConfiguration 主要實(shí)例化了 JndiDestinationResolver,JndiDestinationResolver 是我們上面講到的 DestinationResolver 具體實(shí)現(xiàn),用于將目標(biāo)名稱解釋為 JNDI 位置。

          至此,關(guān)于 JmsAutoConfiguration 注解部分, 及其注解部分的延伸內(nèi)容已經(jīng)講解完畢。下一 節(jié), 我們繼續(xù)學(xué)習(xí) JmsAutoConfiguration 內(nèi)部的自動(dòng)配置實(shí)現(xiàn)。


          JmsAutoC onfiauration 內(nèi)部實(shí)現(xiàn)

          JmsAutoConfiguration 的內(nèi)部代碼部分主要包含兩個(gè)內(nèi)部靜態(tài)類:Jms' TemplateConfi-guration 和 Messaging TemplateConfiguration。

          Jms' TemplateConfiguration 主要用來(lái)初始化 Jms Template 對(duì)象。它的構(gòu)造方法主要設(shè)置了JmsProperties、ObjectProvider和ObjectProvider,參數(shù)的具體功能前面已經(jīng)講過(guò),不再贅述。

          下面看 Jms TemplateConfiguration 中 Jms Template 的初始化。

          @Configuration(proxyBeanMethods = false)
          protected static class Jms TemplateConfiguration {
          .. .
          @Bean
          @Condit ionalOnMissingBean
          @ConditionalOnSingleCandidate(ConnectionFactory. class)
          public Jms Template jmsTemplate(ConnectionFactory connectionFactory) {
          PropertyMapper map = PropertyMapper .get();
          //基于 ConnectionFactory 創(chuàng)建 Jms Template 對(duì)象
          JmsTemplate template = new Jms Template( connectionFactory);
          //沒(méi)置是否為發(fā)布訂閱模式
          template . setPubSubDomain(this . properties . isPubSubDomain());
          map . from(this . dest inat ionResolver: :getIfUnique ) . whenNonNull()
          . to(template: :setDestinationResolver);
          map . from(this . messageConverter :: getIfUnique) . whenNonNull(). to(template: :setMessageConverter);
          mapTemplateProperties(this . properties . getTemplate(),template);
          return template;
          private void mapT emplateProperties (Template properties, JmsTemplate templ
          ate)
          //... Template 的其他參數(shù)設(shè)置
          }
          }

          在初始化 JmsTemplate 的過(guò)程中,明確要求必須只有一個(gè)候選 ConnectionFactory 對(duì)象存在,并且不存在 Jms Template 對(duì)象。

          Jms Template 是用于簡(jiǎn)化同步 JMS 訪問(wèn)代碼的 Helper 類。以上代碼業(yè)務(wù)比較簡(jiǎn)單,就是創(chuàng) 建 了 JmsTemplate 對(duì) 象 , 并 判 斷 DestinationResolver 、 MessageConverter 和JmsPro-perties 中的值是否為 null,如果不為 null 則對(duì) Jms Template 進(jìn)行賦值。

          其中值得注意的是 Jms Template 的 pubSubDomain 的設(shè)置,默認(rèn)情況下為 false,即 P2P模 式 (Point-to-Point ) 。如 果 需 要 設(shè) 置 為 發(fā) 布 - 訂 閱 模 式 (Publish/Subscribe),則需設(shè)置為 true。

          另外一個(gè)內(nèi)部類 Messaging TemplateConfiguration 用來(lái)創(chuàng)建 JmsMessaging Template 對(duì)象。

          @Configuration(proxyBeanMethods = false)
          @ConditionalOnClass (JmsMessagingTemplate. class)
          @Import(JmsTemplateConfiguration. class)
          protected static class MessagingTemplateConfiguration {
          @Bean
          @ConditionalOnMiss ingBean( JmsMessageOperations. class)
          @ConditionalOnSingleCandidate(Jms Template. class)
          public JmsMessagingTemplate jmsMessagingTemplate(JmsProperties propertie
          s,JmsTemplate
          jmsTemplate) {
          JmsMessagingTemplate messagingTemplate = new JmsMessagingTemplate(jms -
          Templ
          ate);
          //沒(méi)置目標(biāo)名稱
          mapTemplateProperties(properties . getTemplate(), messagingTemplate);p
          return
          messagingTemplate;
          private void mapTemplateProperties (Template properties, JmsMessagingTemplatemessagingTemplate) {
          PropertyMapper map = PropertyMapper . get(). alwaysApplyingWhenNonNu1l();
          /沒(méi)置目標(biāo)名稱
          map. from(properties : :getDefaultDestination) . to(messagingTemplate: : setDe
          fault-
          DestinationName);
          }
          }

          當(dāng)類路徑下有 JmsMessagingTemplate 時(shí)才會(huì)觸發(fā)
          MessagingTemplateConfiguration 的自動(dòng)配置。通過(guò)@lmport 注解引入了上面井到的 Jms TemplateConfiguration 配置類, 為了確保 Jms Template 的實(shí)例化,創(chuàng)建、JmsMessagingTemplate 時(shí)將 Jms Template 對(duì)象作為參數(shù), 然后設(shè)置目標(biāo)名稱。

          JmsMessagingTemplate 為 JmsMessageOperations 的具體實(shí)現(xiàn),也是提共 Spring 發(fā)送消息的工具類。自 Spring 4.1 起,JmsMessaging Template 構(gòu)建于 JmsTemplate 之上,提供了消息抽象的集成,例如
          rg.springframework.messaging.Message。

          至此,JmsAuto( Confiauration 相關(guān)的自動(dòng)配置講解完畢,也完成了 JMS 基礎(chǔ)的自動(dòng)配置。


          本文給大家講解的內(nèi)容是SpringBoot消息源碼解析:JMS基礎(chǔ)自動(dòng)配置

          1. 下篇文章給大家講解的是以ActiveMQ為例,講解其自動(dòng)配置的實(shí)現(xiàn);

          2. 覺(jué)得文章不錯(cuò)的朋友可以轉(zhuǎn)發(fā)此文關(guān)注小編;

          3. 感謝大家的支持!


          本文就是愿天堂沒(méi)有BUG給大家分享的內(nèi)容,大家有收獲的話可以分享下,想學(xué)習(xí)更多的話可以到微信公眾號(hào)里找我,我等你哦。


          瀏覽 31
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  超碰免费97 | 综合色图欧美视频 | 欧美亚洲福利 | 全部免费毛片在线播放网站 | 97香蕉久久国产超碰青草专区 |