【源码阅读】看Spring Boot如何自动装配ActiveMQ收发组件

简介: 源于好奇,我研究了一下Spring Boot中ActiveMQ相关组件是如何自动装配的。记录如下。源码路径本文以Spring Boot 1.5.10.RELEASE版本为例。

源于好奇,我研究了一下Spring Boot中ActiveMQ相关组件是如何自动装配的。记录如下。

源码路径

本文以Spring Boot 1.5.10.RELEASE版本为例。

在spring-boot-autoconfigure-1.5.10.RELEASE.jar中的spring.factories文件中可以找到相JMS自动装配类。

org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,\

在spring-jms-4.3.14.RELEASE.jar中包含了jms组件的所有具体功能类。

Configuration类加载顺序

顺序 类名 import引入
1 JndiConnectionFactoryAutoConfiguration
2 ActiveMQAutoConfiguration ActiveMQXAConnectionFactoryConfiguration, ActiveMQConnectionFactoryConfiguration
3 JmsAutoConfiguration JmsAnnotationDrivenConfiguration, JmsBootstrapConfiguration(由JmsAnnotationDrivenConfiguration中的@EnableJms注解引入)

以上罗列出了与ActiveMQ相关的配置类,默认ActiveMQ是采用JMS协议连接的。Spring的JMS消息组件接收与发送是毫不相关的体系。下文分别阐述。

关键类列表

类名 类别 作用
JmsProperties Properties注入 spring.jms开头的配置项注入
ActiveMQProperties Properties注入 spring.activmeq开头的配置项注入
ActiveMQAutoConfiguration @Configuration 无具体代码,通过注解引入ActiveMQXAConnectionFactoryConfiguration与ActiveMQConnectionFactoryConfiguration两个配置类
ActiveMQXAConnectionFactoryConfiguration @Configuration 配置ActiveMQ XA(点击这里了解XA)连接工厂
ActiveMQConnectionFactoryConfiguration @Configuration 配置ActiveMQ连接工厂
JmsAutoConfiguration @Configuration 与发送消息组件相关,初始化JmsTemplate与JmsMessagingTemplate(Spring4.1后引入)
JmsAnnotationDrivenConfiguration @Configuration 与接收消息组件相关,初始化JmsListenerContainerFactory
JmsBootstrapConfiguration @Configuration 初始化JmsListenerAnnotationBeanPostProcessor 与JmsListenerEndpointRegistry两个类的Bean
JmsListenerAnnotationBeanPostProcessor Bean 自定义JmsListenerEndpointRegistrar行为,并将带有@JmsListener的方法注册到指定的JmsListenerContainerFactory中。
JmsListenerEndpointRegistrar Bean 将JmsListenerEndpoint对象注册到JmsListenerEndpointRegistry对象中。

发送消息

发送消息组件的装配相对简单,主要代码都在ActiveMQConnectionFactoryConfigurationJmsAutoConfiguration两个类中。

ActiveMQConnectionFactoryConfiguration

class ActiveMQConnectionFactoryConfiguration {

    @Bean
    @ConditionalOnProperty(prefix = "spring.activemq.pool", name = "enabled", havingValue = "false", matchIfMissing = true)
    public ActiveMQConnectionFactory jmsConnectionFactory(ActiveMQProperties properties,
            ObjectProvider<List<ActiveMQConnectionFactoryCustomizer>> factoryCustomizers) {
        ...
    }

    @Bean(destroyMethod = "stop")
    @ConditionalOnProperty(prefix = "spring.activemq.pool", name = "enabled", havingValue = "true", matchIfMissing = false)
    @ConfigurationProperties(prefix = "spring.activemq.pool.configuration")
    public PooledConnectionFactory pooledJmsConnectionFactory(
                ActiveMQProperties properties,
                ObjectProvider<List<ActiveMQConnectionFactoryCustomizer>> factoryCustomizers) {
            ...
    }

}

可以看到,此类根据配置项的不同初始化了ActiveMQ的连接工厂ActiveMQConnectionFactory或PooledConnectionFactory。

JmsAutoConfiguration

public class JmsAutoConfiguration {

    @Configuration
    protected static class JmsTemplateConfiguration {
        ...
        @Bean
        @ConditionalOnMissingBean
        @ConditionalOnSingleCandidate(ConnectionFactory.class)
        public JmsTemplate jmsTemplate(ConnectionFactory connectionFactory) {
            ...
        }
    }

    @Configuration
    @ConditionalOnClass(JmsMessagingTemplate.class)
    @Import(JmsTemplateConfiguration.class)
    protected static class MessagingTemplateConfiguration {

        @Bean
        @ConditionalOnMissingBean
        @ConditionalOnSingleCandidate(JmsTemplate.class)
        public JmsMessagingTemplate jmsMessagingTemplate(JmsTemplate jmsTemplate) {
            return new JmsMessagingTemplate(jmsTemplate);
        }
    }
}

从源码中可以看到,JmsAutoConfiguration主要作用是当JmsTemplateJmsMessagingTemplate两个类的对象不存在(没有由用户定义)时,初始化这两个类的默认Bean。

至此JMS消息发送关键组件初始化完成。用户可以通过Spring获得JmsTemplateJmsMessagingTemplate对象发送消息。

接收消息

Spring Boot接收消息的方法有好几种(具体请参阅),最简单与常用的方式就是使用@JmsListener注解在方法上。

Spring为每个带有@JmsListener注解的方法在后台构建了一个对应的MessageListenerContainer实例(老版本的Spring需要手动配置DefaultMessageListenerContainer,这里不再赘述)。

为了能自动创建MessageListenerContainer,Spring提供了@EnableJms注解,通过JmsListenerAnnotationBeanPostProcessorBeanPostProcessor机制,指定带有@JmsListener注解的方法为一个MethodJmsListenerEndpoint,并将其通过JmsListenerEndpointRegistrar辅助类注册到JmsListenerEndpointRegistry中。此过程中,需要一个JmsListenerContainerFactory对象(由用户自定义创建或由Spring自动创建DefaultJmsListenerContainerFactory)来参与完成构建动作。几个关键类的关系图大致如下。

img_a512b85caa0f4c844b0f9a8073297bcb.png
JmsListener注册关键类结构图

另外,用户也可以通过实现JmsListenerConfigurer来指定JmsListenerEndpointRegistrar对象在注册过程中的行为。

下面看一下几个核心类的代码。

JmsListenerAnnotationBeanPostProcessor

public class JmsListenerAnnotationBeanPostProcessor
        implements MergedBeanDefinitionPostProcessor, Ordered, BeanFactoryAware, SmartInitializingSingleton {
...
        public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
        ....
                for (Map.Entry<Method, Set<JmsListener>> entry : annotatedMethods.entrySet()) {
                    Method method = entry.getKey();
                    for (JmsListener listener : entry.getValue()) {
                        processJmsListener(listener, method, bean);
                    }
                }
        ...
        }

        protected void processJmsListener(JmsListener jmsListener, Method mostSpecificMethod, Object bean) {
        ...
                this.registrar.registerEndpoint(endpoint, factory);
        }

从以上的源码片段可以看出,JmsListenerAnnotationBeanPostProcessor的主要作用是将带有@JmsListener的方法(Endpoint)注册到JmsListenerContainerFactory中。

JmsAnnotationDrivenConfiguration

class JmsAnnotationDrivenConfiguration {
...
    @Bean
    @ConditionalOnMissingBean
    public DefaultJmsListenerContainerFactoryConfigurer jmsListenerContainerFactoryConfigurer() {
        ...
    }

    @Bean
    @ConditionalOnMissingBean(name = "jmsListenerContainerFactory")
    public DefaultJmsListenerContainerFactory jmsListenerContainerFactory(
            DefaultJmsListenerContainerFactoryConfigurer configurer,
            ConnectionFactory connectionFactory) {
        ...
    }
...
}

从源码可以看出,JmsAnnotationDrivenConfiguration主要作用是当名称为“jmsListenerContainerFactory”的bean不存在时初始化一个DefaultJmsListenerContainerFactory。

至此,接收消息的组件装配过程分析已完成。加上对应的配置项,用户可以从ActiveMQ中收到消息。

相关文章
|
16天前
|
Java 应用服务中间件 Nacos
Spring Cloud 常用各个组件详解及实现原理(附加源码+实现逻辑图)
Spring Cloud 常用各个组件详解及实现原理(附加源码+实现逻辑图)
30 0
|
19天前
|
监控 数据可视化 安全
一套成熟的Spring Cloud智慧工地平台源码,自主版权,开箱即用
这是一套基于Spring Cloud的智慧工地管理平台源码,具备自主版权,易于使用。平台运用现代技术如物联网、大数据等改进工地管理,服务包括建设各方,提供人员、车辆、视频监控等七大维度的管理。特色在于可视化管理、智能报警、移动办公和分布计算存储。功能涵盖劳务实名制管理、智能考勤、视频监控AI识别、危大工程监控、环境监测、材料管理和进度管理等,实现工地安全、高效的智慧化管理。
|
1天前
|
存储 前端开发 Java
Spring Boot自动装配的源码学习
【4月更文挑战第8天】Spring Boot自动装配是其核心机制之一,其设计目标是在应用程序启动时,自动配置所需的各种组件,使得应用程序的开发和部署变得更加简单和高效。下面是关于Spring Boot自动装配的源码学习知识点及实战。
11 1
|
2天前
|
传感器 人工智能 前端开发
JAVA语言VUE2+Spring boot+MySQL开发的智慧校园系统源码(电子班牌可人脸识别)Saas 模式
智慧校园电子班牌,坐落于班级的门口,适合于各类型学校的场景应用,班级学校日常内容更新可由班级自行管理,也可由学校统一管理。让我们一起看看,电子班牌有哪些功能呢?
41 4
JAVA语言VUE2+Spring boot+MySQL开发的智慧校园系统源码(电子班牌可人脸识别)Saas 模式
|
3天前
|
XML Java 数据库
【SpringBoot:详解Bean装配】
【SpringBoot:详解Bean装配】
10 3
|
9天前
|
设计模式 安全 Java
【初学者慎入】Spring源码中的16种设计模式实现
以上是威哥给大家整理了16种常见的设计模式在 Spring 源码中的运用,学习 Spring 源码成为了 Java 程序员的标配,你还知道Spring 中哪些源码中运用了设计模式,欢迎留言与威哥交流。
|
10天前
|
缓存 Java 开发者
10个点介绍SpringBoot3工作流程与核心组件源码解析
Spring Boot 是Java开发中100%会使用到的框架,开发者不仅要熟练使用,对其中的核心源码也要了解,正所谓知其然知其所以然,V 哥建议小伙伴们在学习的过程中,一定要去研读一下源码,这有助于你在开发中游刃有余。欢迎一起交流学习心得,一起成长。
|
14天前
|
Java
SpringBoot之@Conditional衍生条件装配详解
SpringBoot之@Conditional衍生条件装配详解
|
14天前
|
XML 人工智能 Java
Spring Bean名称生成规则(含源码解析、自定义Spring Bean名称方式)
Spring Bean名称生成规则(含源码解析、自定义Spring Bean名称方式)
|
20天前
|
Java Maven Nacos
Spring Cloud Eureka 服务注册和服务发现超详细(附加--源码实现案例--及实现逻辑图)
Spring Cloud Eureka 服务注册和服务发现超详细(附加--源码实现案例--及实现逻辑图)
31 0