rocketmq集成springboot源码分析

我们知道无论是mybatis-plus、rocketmq等第三方优秀的框架都继承了springboot。那么如果我们想自己写一个简单的功能集成到springboot当中需要怎么做到呢?

接下来我们分下下rocketmq集成springboot的代码:

@RocketMQMessageListener是我们实现业务代码的监听实现类,通常它长这个样子:

@Slf4j
@Component
@RocketMQMessageListener(topic = TopicConst.REFERENCE_CODE_CREATE_SEND_EMAIL_SMS_TOPIC, consumerGroup = "txn_create_send_email_sms_consumer")
public class ReferenceCodeCreateNotifyConsumer implements RocketMQListener {
//业务代码
}

我们的一个linstener要想集成到rocketmq还需要很多的参数,这些参数统一的包装在了DefaultRocketMQListenerContainer实现类当中,并且DefaultRocketMQListenerContainer里面包含了一个DefaultMQPushConsumer实例。有了DefaultMQPushConsumer实例,我们就可以启动它实现一个rocketmq consumer端服务实例。

具体地:

1、rocketmq实现了RocketMQAutoConfiguration

注解实现了以下4个主要步骤。

1.1、@EnableConfigurationProperties(RocketMQProperties.class)

感知我们配置文件当中有关rocketmq的配置信息

1.2、@ConditionalOnClass({MQAdmin.class})

通过MQAdmin.class感知rocketmq-client包是否在类路径当中。

1.3、@Import({MessageConverterConfiguration.class, ListenerContainerConfiguration.class, ExtProducerResetConfiguration.class,

引入RocketMQMessageConverter实例

引入ListenerContainerConfiguration实例

引入ExtProducerResetConfiguration实例

引入ExtConsumerResetConfiguration实例

引入RocketMQTransactionConfiguration实例

引入RocketMQListenerConfiguration实例

1.4、@AutoConfigureAfter({MessageConverterConfiguration.class})

注册RocketMQMessageListenerBeanPostProcessor 为RootBeanDefinition

类型实例。

RocketMQAutoConfiguration内部实现了以下两个步骤。

1、如果配置参数里面有name-server和producer.group,则注册DefaultMQProducer实例

2、如果配置参数里面有name-server、pull-consumer.group和pull-consumer.topic

,则注册DefaultLitePullConsumer实例。

再来看RocketMQMessageListenerBeanPostProcessor,其实现了BeanPostProcessor

接口,每一个类初始化之前和之后都会走到这个类的postProcessBeforeInitialization

和postProcessAfterInitialization方法当中。

Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        Class targetClass = AopUtils.getTargetClass(bean);
        RocketMQMessageListener ann = targetClass.getAnnotation(RocketMQMessageListener.class);
        if (ann != null) {
            RocketMQMessageListener enhance = enhance(targetClass, ann);
            if (listenerContainerConfiguration != null) {
                listenerContainerConfiguration.registerContainer(beanName, bean, enhance);
            }
        }
        return bean;
    }

当我们实现业务代码的监听类走到该方法的时候,会被感知到,并注册响应的container到spring上下文。

container的初始化肯定是会涉及到rocektmq启动需要的一大堆参数,这个不表,我们看下其初始化最重要的三件事儿

1、获取我们监听配置的topic、tag、group

2、获取配置文件中配置的参数,命名空间、nameserver等

3、最重要的是DefaultRocketMQListenerContainer实现了InitializingBean。当DefaultRocketMQListenerContainer初始化完毕之后会执行afterPropertiesSet方法。该方法里面包含了初始化consumer代码。

注意consumer里面的参数一部分是在DefaultRocketMQListenerContainer当中写死了,一部分则来自RocketMQMessageListener当中的配置,也就是说我们可以通过注解RocketMQMessageListener动态设定一些参数。

this.consumeMode = anno.consumeMode();
        this.consumeThreadMax = anno.consumeThreadNumber();
        this.consumeThreadNumber = anno.consumeThreadNumber();
        this.messageModel = anno.messageModel();
        this.selectorType = anno.selectorType();
        this.selectorExpression = anno.selectorExpression();
        this.consumeTimeout = anno.consumeTimeout();
        this.maxReconsumeTimes = anno.maxReconsumeTimes();
        this.replyTimeout = anno.replyTimeout();
        this.tlsEnable = anno.tlsEnable();
        this.namespace = anno.namespace();
        this.delayLevelWhenNextConsume = anno.delayLevelWhenNextConsume();
        this.suspendCurrentQueueTimeMillis = anno.suspendCurrentQueueTimeMillis();
        this.awaitTerminationMillisWhenShutdown = Math.max(0, anno.awaitTerminationMillisWhenShutdown());
        this.instanceName = anno.instanceName();

以上参数都可以通过监听配置参数调整。

        consumer实例有了接下来就是如何启动.返回到container注册方法,当它初始化完DefaultRocketMQListenerContainer之后随机就启动了container,container启动随即就启动了consumer.这样回到图一,思路就清晰了。springboot整合rocketmq,每一个监听配置一个DefaultRocketMQListenerContainer,每一个DefaultRocketMQListenerContainer包含一个consumer,通过springboot的autoconfig方式将每一个RocketMQMessageListener实现类包装成一个DefaultRocketMQListenerContainer,最终由DefaultRocketMQListenerContainer来桥接我们的监听和consumer去实现功能。

 

你可能感兴趣的:(rocketmq系列,spring,boot,java-rocketmq,rocketmq)