SpringBoot消息源码:JmsListener注解解析JmsListener注解解析
JMS 消息分发送消息和接收消息两种功能,发送消息很简单,注⼊ Jms Template 到对应的Bean 中即可使⽤。接收消息则需要使⽤
@JmsListener 注解。
先看⼀下发送消息的官⽅⽰例。
@Component
public class MyBean {
private final JmsTemplate jmsTemplate;
@Autowired
public MyBean(JmsTemplate jmsTemplate) {
this. jmsTemplate = jmsTemplate;
}
将 JmsTemplate 注⼊ MyBean 中,便可在该类的其他⽅法中使⽤ JmsTemplate 来发送消息了。
接收消息的官⽅代码⽰例如下。
@Component
public class MyBean
@JmsListener(destination = " someQueue")
public void processMessage(String content) {
// ...
}
}
当 JMS 的基础构件都完成初始化之后,可以使⽤@JmsListener 注释任何 Bean 来创建侦听器端点,就像上⾯的⽰例⼀样。
@JmsListener 注解是由 Spring 提供的,它位于 spring-jms 包下。 Spring 会对注解了@JmsListener 的 ⽅ 法 进 ⾏ 处 理 。 在 这 ⼀过 程 中 主 要 使 ⽤ 到 同 ⼀ 包 下 的
JmsListenerAnnotation-BeanPostProcessor 类。该类中相关解析代码如下。
@Override
public object postProcessAfterInitialization(0bject bean, String beanName )
throws
BeansException
if (bean instanceof AopInfrastructureBean| bean instanceof JmsListener-
ContainerFactory|I
bean instanceof JmsListenerEndpointRegistry) {
//忽略诸如作⽤域代理之类的 AOP 基础结构
return bean;
//通过⼯具类 AopProxyUtils 获取最终的 Class 对象
Class<?> targetClass = AopProxyUtils . ultimateTargetClass(bean);//如果该⽬标 Class 不包含在 nonAnnotatedClasses(没有被炷解的类)
//并且⽬标 Class 为基 FJmsListener 的候选类
if (!this . nonAnnotatedClasses . contains(targetClass) &&
AnnotationUtils. isCandidateClass(targetClass, JmsListener.class)) {
//获取该类炷解有 Jmslistener 的⽅法集合
Map<Method, Set<JmsListener>> annotatedMethods = MethodIntrospector.
selec tMethods(targetClass,
(MethodIntrospector . MetadataLookup<Set<Jmslistener>>) met
hod -> {
Set<JmsListener> listenerMethods = AnnotatedE lementUtil
getMergedRepeatableAnnotations (
method, JmsListener.class, JmsL isteners. class);
return ( !listenerMethods . isEmpty() ? listenerMethods : nu
11);
});
if (annotatedMethods . isEmpty()) {
//该类⽅法为空,则将该类放⼊ nonAnnotatedClasses 中
this . nonAnnotatedClasses . add(targetClass);
else
/如果⽅法集合不为空,则遍历⽅法集合并调⽤ processJmsL istener ⽅法进⾏后续
处理springboot aop
annotatedMethods . forEach( (method, listeners)- >
listeners. forEach(listener -> processJmslisten
er(listener, method,
bean)));
return bean;
}
在上述代码中,核⼼的处理流程就是通过 Bean 获取最终符合条件的 Class 对象,然后获取该 Class 对象中被@JmsListener 注解的⽅法集合,遍历调⽤ processJmsListener ⽅法进⾏对应的注册操作。
在 processJmsListener ⽅ 法中主要就是创建并初始化 MethodJmsListenerEndpoint 对象,同时创建了JmsListenerContainerFactory 对象,然后通过 JmsListenerEndpointRegistrar的 registerEndpoint ⽅法将其进⾏注册
到 JmsListenerContainerFactory 中。
因此,在代码中通过注解@JmsListener 便可进⾏消息的接收了。processJmsListener 部分代码如下。
protected void processJmsListener(JmsListener jmsListener, Method mostScific-Method, object bean) {
Method invocableMethod = AopUtils . selectInvocableMethod (mostSpecificMetho
d, bean. getClass());
MethodImsListenerEndpoint endpoint = createMethodImslistenerEndpoint();
endpoint. setBean(bean);
// ... 省略⼤量 set ⽅法
//创建 JmsL istenerContainerFactory
JmsListenerContainerFactory<?> factory = null;
String containerFactoryBeanName = resolve ( jmsL istener. containerFactory
());
if (StringUtils . hasText(containerFactoryBeanName)) {
Assert. state (this. beanFactory != null, "BeanFactory must be set to obta
container factory by bean name") ;
try
factory = this. beanFactory . getBean(containerF actoryBeanN
ame, JmsL istener-
ContainerFactory.clas
s);
} catch (NoSuchBeanDefinitionException ex) {
//通过 JmsL istenerEndpointRegistrar 进⾏注册
this . registrar. registerEndpoint(endpoint, factory);
}
默认情况下,当使⽤了@JmsListener 注解,⽽⼜没有⾃定义 JmsL istenerContainer-Factory时,Spring Boot 会⾃动创建⼀个默认的对象。
如果想创建多个
JmsListenerContainerFactory,可使⽤ Spring Boot 提供的DefaultJmsListenerContainerFactoryConfigurer 来创建,⽰例代码如下。
@Configuration
static class JmsConfiguration {
@Bean
public DefaultJmsListenerContainerFactory myFactory(
DefaultJmsListenerContainerFactoryConfigurer configurer) {
DefaultJmsListenerContainerFactory factory =
new DefaultJmsListenerContainerFactory();
configurer . configure(factory, connectionFactory());
factory. setMessageConverter (myMessageConverter());
return factory;}
}
上 ⾯ 代 码 定 义 完
JmsListenerContainerFactory 之 后 , 在 @JmsListener 注 解 中 指 定
containerFactory 为对应的 Factory 名字(myFactory) 即可。
关于@JmsListener 的使⽤及原理,我们就讲到这⾥。
⼩结
本章重点分析了 Spring Boot 中 JMS 和 ActiveMQ 的⾃动配置。ActiveMQ 很 好地实现了JMS 协议,同时⼜可以很⽅便地进⾏定制化实现。针对 JMS 的注解部分,Spring Boot 也提供了专门的⾃动配置类
JmsAnnotationDrivenConfiguration 进⾏⼀系列的默认配置 ,本章并未进⾏讲解,读者朋友可⾃⾏阅读。⽽关于其他协议的⾃动配置实现基本相似,⼤家可进-步查看相关源代码。
本⽂给⼤家讲解的内容是SpringBoot消息源码解析:JmsListener注解解析
1. 下篇⽂章给⼤家讲解的是SpringBootCache源码解析:Cache⾃动配置;
2. 觉得⽂章不错的朋友可以转发此⽂关注⼩编;
3. 感谢⼤家的⽀持!

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。