1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        SpringBoot消息源碼解析:JMS基礎自動配置

        共 9618字,需瀏覽 20分鐘

         ·

        2022-04-25 07:51


        SpringBoot消息源碼解析

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

        同時,Spring Boot 也為 RabbitTemplate 和 Rabbit MQ 提供了自動配置選項。Spring Boot通過自動配置對 ActiveMQ、RabbitMQ 和 Apache Kafka 提供了支持。本章重點講解 SpringBoot 對 JMS 和 ActiveMQ 的自動配置操作。

        JMS 基礎自動配置

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

        在 Spring Boot 中,通過 JmsAutoConfiguration 自動配置來完成 JMS 的基礎組件的初始化。

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

        # 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 類的條件才會進行初始化。

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

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

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

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

        @Import 引入了
        JmsAnnotationDrivenConfiguration 配置,該配置類主要用于 Spring4.1 注解驅動的 JMS 的自動配置。

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

        @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 為一個注解類,@EnableJms 用于開啟 JMS 注解,使@JmsListener 注解生效。

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

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

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

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

        Jta TransactionManager 是
        PlatformTransactionManager 的實現(xiàn)類,它提供了 Spring 的JTA 事務管理,也可用于分布式事務的管理。關于事務相關的內容,在此不進行展開。

        MessageConverter 是一個策略接口, 用于指定 Java 對象和 JMS 消息之間的轉換器。

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

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

        通過 MessageConverter 接口方法的定義也能夠看出它的核心功能就是進行 Java 對象與JMS 消息之間的轉換。

        了解完構法我們先看
        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)建一個
        DefaultJmsListenerContainerFactoryConfigurer 對象,然后將上面構造方法傳入的參數(shù)設置到 DefaultJmsListenerContainerFactoryConfigurer 對象中。該類的作用是配置DefaultJmsListenerContainerFactory通過DefaultJmsListenerContainerFact-oryConfigurer 中的 configure 方法將構造方法中的參數(shù)項賦值給 DefaultJmsListenerContainer-Factory.而 DefaultJmsListenerContainerFactory是個 JmsListenerContainerFactory 實現(xiàn),

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

        接下來便是
        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;
        }

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


        JmsAnnotationDrivenConfiguration 剩余部分代碼定義了兩個內部類,代碼如下。

        @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;
        }
        }

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

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

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


        JmsAutoC onfiauration 內部實現(xiàn)

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

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

        下面看 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 對象
        JmsTemplate template = new Jms Template( connectionFactory);
        //沒置是否為發(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ù)設置
        }
        }

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

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

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

        另外一個內部類 Messaging TemplateConfiguration 用來創(chuàng)建 JmsMessaging Template 對象。

        @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);
        //沒置目標名稱
        mapTemplateProperties(properties . getTemplate(), messagingTemplate);p
        return
        messagingTemplate;
        private void mapTemplateProperties (Template properties, JmsMessagingTemplatemessagingTemplate) {
        PropertyMapper map = PropertyMapper . get(). alwaysApplyingWhenNonNu1l();
        /沒置目標名稱
        map. from(properties : :getDefaultDestination) . to(messagingTemplate: : setDe
        fault-
        DestinationName);
        }
        }

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

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

        至此,JmsAuto( Confiauration 相關的自動配置講解完畢,也完成了 JMS 基礎的自動配置。


        本文給大家講解的內容是SpringBoot消息源碼解析:JMS基礎自動配置

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

        2. 覺得文章不錯的朋友可以轉發(fā)此文關注小編;

        3. 感謝大家的支持!


        本文就是愿天堂沒有BUG給大家分享的內容,大家有收獲的話可以分享下,想學習更多的話可以到微信公眾號里找我,我等你哦。


        瀏覽 31
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            无码A级片| 手伸进老师湿润的三角裤 | 又黄又湿的视频 | 北条麻妃与黑人aⅴ片hd | 苍井空一二三 | 免费无码婬片AAAA在线观看 | 极品丝袜乱系列全集 | 午夜福利激情 | 日韩一级a视频 | 你的欲梦裸身视频在线观看网站 |