博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SpringBoot2.0源码分析(二):整合ActiveMQ分析
阅读量:5789 次
发布时间:2019-06-18

本文共 5680 字,大约阅读时间需要 18 分钟。

SpringBoot具体整合ActiveMQ可参考:

ActiveMQ自动注入

当项目中存在javax.jms.Messageorg.springframework.jms.core.JmsTemplate着两个类时,SpringBoot将ActiveMQ需要使用到的对象注册为Bean,供项目注入使用。一起看一下JmsAutoConfiguration类。

@Configuration@ConditionalOnClass({ Message.class, JmsTemplate.class })@ConditionalOnBean(ConnectionFactory.class)@EnableConfigurationProperties(JmsProperties.class)@Import(JmsAnnotationDrivenConfiguration.class)public class JmsAutoConfiguration {	@Configuration	protected static class JmsTemplateConfiguration {	    ......		@Bean		@ConditionalOnMissingBean		@ConditionalOnSingleCandidate(ConnectionFactory.class)		public JmsTemplate jmsTemplate(ConnectionFactory connectionFactory) {			PropertyMapper map = PropertyMapper.get();			JmsTemplate template = new JmsTemplate(connectionFactory);			template.setPubSubDomain(this.properties.isPubSubDomain());			map.from(this.destinationResolver::getIfUnique).whenNonNull()					.to(template::setDestinationResolver);			map.from(this.messageConverter::getIfUnique).whenNonNull()					.to(template::setMessageConverter);			mapTemplateProperties(this.properties.getTemplate(), template);			return template;		}            ......	}	@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);		}	}}复制代码

RabbitAutoConfiguration主要注入了jmsMessagingTemplatejmsTemplateRabbitAutoConfiguration同时导入了RabbitAnnotationDrivenConfiguration,注入了jmsListenerContainerFactory

消息发送

以下面的发送为例:

jmsMessagingTemplate.convertAndSend(this.queue, msg);复制代码

这个方法会先对消息进行转换,预处理,最终通过调用JmsTemplate的doSend实现消息发送的。

protected void doSend(Session session, Destination destination, MessageCreator messageCreator)			throws JMSException {		Assert.notNull(messageCreator, "MessageCreator must not be null");		MessageProducer producer = createProducer(session, destination);		try {			Message message = messageCreator.createMessage(session);			doSend(producer, message);			if (session.getTransacted() && isSessionLocallyTransacted(session)) {				JmsUtils.commitIfNecessary(session);			}		}		finally {			JmsUtils.closeMessageProducer(producer);		}	}复制代码

首先创建一个MessageProducer的实例,接着将最初的org.springframework.messaging.Message转换成javax.jms.Message,再将消息委托给producer进行发送。

消息接收

先看一个消费的事例:

@Componentpublic class Consumer {	@JmsListener(destination = "sample.queue")	public void receiveQueue(String text) {		System.out.println(text);	}}复制代码

SpringBoot会去解析@JmsListener,具体实现在JmsListenerAnnotationBeanPostProcessorpostProcessAfterInitialization方法。

public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {		if (!this.nonAnnotatedClasses.contains(bean.getClass())) {			Class
targetClass = AopProxyUtils.ultimateTargetClass(bean); Map
> annotatedMethods = MethodIntrospector.selectMethods(targetClass, (MethodIntrospector.MetadataLookup
>) method -> { Set
listenerMethods = AnnotatedElementUtils.getMergedRepeatableAnnotations( method, JmsListener.class, JmsListeners.class); return (!listenerMethods.isEmpty() ? listenerMethods : null); }); if (annotatedMethods.isEmpty()) { this.nonAnnotatedClasses.add(bean.getClass()); } else { annotatedMethods.forEach((method, listeners) -> listeners.forEach(listener -> processJmsListener(listener, method, bean))); } } return bean; }复制代码

SpringBoot根据注解找到了使用了@JmsListener注解的方法,当监听到ActiveMQ收到的消息时,会调用对应的方法。来看一下具体怎么进行listener和method的绑定的。

protected void processJmsListener(JmsListener jmsListener, Method mostSpecificMethod, Object bean) {		Method invocableMethod = AopUtils.selectInvocableMethod(mostSpecificMethod, bean.getClass());		MethodJmsListenerEndpoint endpoint = createMethodJmsListenerEndpoint();		endpoint.setBean(bean);		endpoint.setMethod(invocableMethod);		endpoint.setMostSpecificMethod(mostSpecificMethod);		endpoint.setMessageHandlerMethodFactory(this.messageHandlerMethodFactory);		endpoint.setEmbeddedValueResolver(this.embeddedValueResolver);		endpoint.setBeanFactory(this.beanFactory);		endpoint.setId(getEndpointId(jmsListener));		endpoint.setDestination(resolve(jmsListener.destination()));		if (StringUtils.hasText(jmsListener.selector())) {			endpoint.setSelector(resolve(jmsListener.selector()));		}		if (StringUtils.hasText(jmsListener.subscription())) {			endpoint.setSubscription(resolve(jmsListener.subscription()));		}		if (StringUtils.hasText(jmsListener.concurrency())) {			endpoint.setConcurrency(resolve(jmsListener.concurrency()));		}		JmsListenerContainerFactory
factory = null; String containerFactoryBeanName = resolve(jmsListener.containerFactory()); if (StringUtils.hasText(containerFactoryBeanName)) { Assert.state(this.beanFactory != null, "BeanFactory must be set to obtain container factory by bean name"); try { factory = this.beanFactory.getBean(containerFactoryBeanName, JmsListenerContainerFactory.class); } catch (NoSuchBeanDefinitionException ex) { throw new BeanInitializationException("Could not register JMS listener endpoint on [" + mostSpecificMethod + "], no " + JmsListenerContainerFactory.class.getSimpleName() + " with id '" + containerFactoryBeanName + "' was found in the application context", ex); } } this.registrar.registerEndpoint(endpoint, factory); }复制代码

先设置endpoint的相关属性,再获取jmsListenerContainerFactory,最后将endpoint注册到jmsListenerContainerFactory


本篇到此结束,如果读完觉得有收获的话,欢迎点赞、关注、加公众号【贰级天災】,查阅更多精彩历史!!!

转载地址:http://lwhyx.baihongyu.com/

你可能感兴趣的文章
Webpack中的sourcemap以及如何在生产和开发环境中合理的设置sourcemap的类型
查看>>
做完小程序项目、老板给我加了6k薪资~
查看>>
java工程师linux命令,这篇文章就够了
查看>>
关于React生命周期的学习
查看>>
webpack雪碧图生成
查看>>
搭建智能合约开发环境Remix IDE及使用
查看>>
Spring Cloud构建微服务架构—服务消费基础
查看>>
RAC实践采坑指北
查看>>
runtime运行时 isa指针 SEL方法选择器 IMP函数指针 Method方法 runtime消息机制 runtime的使用...
查看>>
LeetCode36.有效的数独 JavaScript
查看>>
Scrapy基本用法
查看>>
PAT A1030 动态规划
查看>>
自制一个 elasticsearch-spring-boot-starter
查看>>
【人物志】美团前端通道主席洪磊:一位产品出身、爱焊电路板的工程师
查看>>
一份关于数据科学家应该具备的技能清单
查看>>
机器学习实战_一个完整的程序(一)
查看>>
Web框架的常用架构模式(JavaScript语言)
查看>>
如何用UPA优化性能?先读懂这份报告!
查看>>
这些Java面试题必须会-----鲁迅
查看>>
Linux 常用命令
查看>>