Spring
加载RocketMq
消费者实例后会立即开始消费,不论Spring
容器是否初始化完毕。这就意味着如果Spring
容器由于某种原因导致容器初始化失败,但应用程序没有因为容器初始化失败而关闭,那么会出现不可预期的后果,例如Spring
容器初始化失败,导致定时任务不能正常执行,而MQ
消费需要定时任务从数据库中拉取的配置信息,这样会导致MQ
消费失败。因此,可以在Spring
容器启动完成后再初始化MQ
消费者。
通过XML
或Java
配置Bean
,都可以指定lazy-init
的属性,它有true
和false
两个值
true:延时加载,当有其他Bean有引用此Bean时或者主动调用BeanFactory#getBean方法时才会进行初始化
false:立即加载
如果你只使用了lazy-init = true
,MQ
消费者并不会启动,如上所说,当有其他Bean有引用此Bean时或者主动调用BeanFactory#getBean方法才会进行初始化。
延时初始化MQ消费者示例:
配置
<!-- 自定义实现的消息监听 -->
<bean name="messageListenerImpl" class="com.MessageListenerImpl"/>
<!-- 消费者实例 -->
<bean id="consumer" class="org.apache.rocketmq.client.consumer.DefaultMQPushConsumer" init-method="start"
destroy-method="shutdown" lazy-init="true">
<property name="namesrvAddr" value="1.1.1.1:9876"/>
<property name="instanceName" value="push"/>
<property name="consumerGroup" value="CONSUMER_GROUP"/>
<property name="subscription">
<map>
<entry key="TOPIC" value="TAGS"/>
</map>
</property>
<property name="messageListener" ref="messageListenerImpl"/>
<property name="consumeThreadMin" value="2"/>
<property name="consumeThreadMax" value="4"/>
<property name="consumeMessageBatchMaxSize" value="1"/>
</bean>
消费监听
public class MessageListenerImpl implements MessageListenerConcurrently {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
try {
for (MessageExt message : msgs) {
}
} catch (Exception e) {
e.printStackTrace();
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
}
使用Spring
容器监听器,在容器启动成功后初始化MQ
消费者
// 一个应用中可以有多个ApplicationListener,先加载的先执行
@Component
public class RocketMqInit implements ApplicationListener<ContextStartedEvent> {
@Resource
private ApplicationContext applicationContext;
@Override
public void onApplicationEvent(ContextStartedEvent event) {
applicationContext.getBean(DefaultMQPushConsumer.class);
}
}