经验大分享:spring项目在启动的时候执行方法初始化

简介: 经验大分享:spring项目在启动的时候执行方法初始化

说明:老项目,使用的是spring 3项目,需要对接RocketMQ,配置完之后,在消费者监听方法中,发现业务处理service注入不进来,最后检查发现是因为消费者监听工具类没有被正确的初始化,所以它里边的业务service注入之后是个null,于是各种折腾,特此记录一下

方式一:

解决:对需要初始化的类实现InitializingBean接口,重写afterPropertiesSet()方法,在afterPropertiesSet方法中调用需要被初始化的方法

代码如下:

import xx.xxx.component.BaseServiceMqConsumer;

import xx.xxx.service.VideoConsumerService;

import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;

import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;

import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;

import //代码效果参考:http://www.zidongmutanji.com/zsjx/546609.html

org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;

import org.apache.rocketmq.client.exception.MQClientException;

import org.apache.rocketmq.common.message.MessageExt;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.InitializingBean;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.annotation.DependsOn;

import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;

import java.util.List;

@DependsOn("RocketMqConfig")

@Component

public class RocketMqConsumerUtil implements InitializingBean //代码效果参考:http://www.zidongmutanji.com/zsjx/304231.html

{

private static Logger log = LoggerFactory.getLogger(RocketMqConsumerUtil.class);

@Autowired

private VideoConsumerService videoConsumerService;

/

接收消息

/

public void listener(){

// 获取消息生产者

DefaultMQPushConsumer consumer = BaseServiceMqConsumer.getDefaultMQPushConsumer();

// 订阅主体

try {

consumer.subscribe(RocketMqUtil.topic, "*");

consumer.registerMessageListener(new MessageListenerConcurrently() {

/

默认msgs里只有一条消息,可以通过设置consumeMessageBatchMaxSize参数来批量接收消息

/

public ConsumeConcurrentlyStatus consumeMessage(

List[/span>MessageExt

MessageExt messageExt = msgs.get(0);

String msg = null;

try {

msg = new String(messageExt.getBody(),"utf-8");

} catch (UnsupportedEncodingException e) {

log.error("消息编码失败,MsgBody:{}",new String(messageExt.getBody()));

e.printStackTrace();

}

log.info("消费开始-MsgBody:{}",msg);

// String msg = new String(messageExt.getBody());

// log.info("MsgBody:{}",new String(messageExt.getBody()));

if (messageExt.getTopic().equals(RocketMqUtil.topic)) {

// topic的消费逻辑

if (messageExt.getTags() != null && messageExt.getTags().equals(RocketMqUtil.tag)) {

// 根据Tag消费消息,具体消费消息的业务方法

videoConsumerService.dealVideoMsg(msg);

}

} else if (messageExt.getTopic().equals("TopicTest2")) {

// 执行TopicTest2的消费逻辑

}

return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;

}

});

/**

Consumer对象在使用之前必须要调用start初始化,初始化一次即可[/span>br

/

consumer.start();

log.info("rocketmq-consumer 启动成功---");

} catch (MQClientException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

@Override

public void afterPropertiesSet() throws Exception {

listener();//调用需要被初始化的方法

}

}

方式二:

使用注解@PostContruct 指定需要被初始化执行的方法

package net.greatsoft.xxx.utils;

import xxx.xxx.component.BaseServiceMqConsumer;

import net.greatsoft.xxx.service.VideoConsumerService;

import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;

import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;

import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;

import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;

import org.apache.rocketmq.client.exception.MQClientException;

import org.apache.rocketmq.common.message.MessageExt;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.InitializingBean;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.annotation.DependsOn;

import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

import java.io.UnsupportedEncodingException;

import java.util.List;

@DependsOn("RocketMqConfig")

@Component

public class RocketMqConsumerUtil {

private static Logger log = LoggerFactory.getLogger(RocketMqConsumerUtil.class);

@Autowired

private VideoConsumerService videoConsumerService;

/**

接收消息8

/

@PostConstruct

public void listener(){

// 获取消息生产者

DefaultMQPushConsumer consumer = BaseServiceMqConsumer.getDefaultMQPushConsumer();

// 订阅主体

try {

consumer.subscribe(RocketMqUtil.topic, "");

consumer.registerMessageListener(new MessageListenerConcurrently() {

/

默认msgs里只有一条消息,可以通过设置consumeMessageBatchMaxSize参数来批量接收消息

* /

public ConsumeConcurrentlyStatus consumeMessage(

List[/span>MessageExt

MessageExt messageExt = msgs.get(0);

String msg = null;

try {

msg = new String(messageExt.getBody(),"utf-8");

} catch (UnsupportedEncodingException e) {

log.error("消息编码失败,MsgBody:{}",new String(messageExt.getBody()));

e.printStackTrace();

}

log.info("消费开始-MsgBody:{}",msg);

if (messageExt.getTopic().equals(RocketMqUtil.topic)) {

// topic的消费逻辑

if (messageExt.getTags() != null && messageExt.getTags().equals(RocketMqUtil.tag)) {

// 根据Tag消费消息,具体消费消息的业务方法

videoConsumerService.dealVideoMsg(msg);

}

} else if (messageExt.getTopic().equals("TopicTest2")) {

// 执行TopicTest2的消费逻辑

}

return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;

}

});

/

Consumer对象在使用之前必须要调用start初始化,初始化一次即可[/span>br

/

consumer.start();

log.info("rocketmq-consumer 启动成功---");

} catch (MQClientException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

方式三:

在spring的xml配置文件中使用 的init 属性来执行初始化的Bean

[/span>bean id="rocketMqConsumerUtil" class="xx.xxx.utils.RocketMqConsumerUtil"

scope="singleton" init-method="listener"/>

package net.greatsoft.jinNanHealth.utils;

import net.greatsoft.jinNanHealth.component.BaseServiceMqConsumer;

import net.greatsoft.jinNanHealth.service.VideoConsumerService;

import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;

import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;

import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;

import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;

import org.apache.rocketmq.client.exception.MQClientException;

import org.apache.rocketmq.common.message.MessageExt;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.InitializingBean;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.annotation.DependsOn;

import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

import java.io.UnsupportedEncodingException;

import java.util.List;

/

@author xc

@date 2020-07-23

* /

@DependsOn("RocketMqUtil")

@Component

public class RocketMqConsumerUtil {

private static Logger log = LoggerFactory.getLogger(RocketMqConsumerUtil.class);

@Autowired

private VideoConsumerService videoConsumerService;

/

接收消息8

/

public void listener(){

// 获取消息生产者

DefaultMQPushConsumer consumer = BaseServiceMqConsumer.getDefaultMQPushConsumer();

// 订阅主体

try {

consumer.subscribe(RocketMqUtil.topic, "");

consumer.registerMessageListener(new MessageListenerConcurrently() {

/**

默认msgs里只有一条消息,可以通过设置consumeMessageBatchMaxSize参数来批量接收消息

/

public ConsumeConcurrentlyStatus consumeMessage(

List[/span>MessageExt

MessageExt messageExt = msgs.get(0);

String msg = null;

try {

msg = new String(messageExt.getBody(),"utf-8");

} catch (UnsupportedEncodingException e) {

log.error("消息编码失败,MsgBody:{}",new String(messageExt.getBody()));

e.printStackTrace();

}

            log.info("消费开始-MsgBody:{}",msg);

if (messageExt.getTopic().equals(RocketMqUtil.topic)) {

// topic的消费逻辑

if (messageExt.getTags() != null && messageExt.getTags().equals(RocketMqUtil.tag)) {

// 根据Tag消费消息,具体消费消息的业务方法

videoConsumerService.dealVideoMsg(msg);

}

} else if (messageExt.getTopic().equals("TopicTest2")) {

// 执行TopicTest2的消费逻辑

}

return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;

}

});

/*

Consumer对象在使用之前必须要调用start初始化,初始化一次即可[/span>br

* /

consumer.start();

log.info("rocketmq-consumer 启动成功---");

} catch (MQClientException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

相关实践学习
消息队列RocketMQ版:基础消息收发功能体验
本实验场景介绍消息队列RocketMQ版的基础消息收发功能,涵盖实例创建、Topic、Group资源创建以及消息收发体验等基础功能模块。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
相关文章
|
10天前
|
Java Spring
【Spring】方法注解@Bean,配置类扫描路径
@Bean方法注解,如何在同一个类下面定义多个Bean对象,配置扫描路径
137 73
|
10天前
|
存储 JSON 前端开发
【Spring项目】表白墙,留言板项目的实现
本文主要介绍了表白墙项目的实现,包含前端和后端代码,以及测试
|
10天前
|
JSON 前端开发 Java
|
10天前
|
缓存 前端开发 Java
【Spring】——SpringBoot项目创建
SpringBoot项目创建,SpringBootApplication启动类,target文件,web服务器,tomcat,访问服务器
|
2月前
|
缓存 Java Spring
实战指南:四种调整 Spring Bean 初始化顺序的方案
本文探讨了如何调整 Spring Boot 中 Bean 的初始化顺序,以满足业务需求。文章通过四种方案进行了详细分析: 1. **方案一 (@Order)**:通过 `@Order` 注解设置 Bean 的初始化顺序,但发现 `@PostConstruct` 会影响顺序。 2. **方案二 (SmartInitializingSingleton)**:在所有单例 Bean 初始化后执行额外的初始化工作,但无法精确控制特定 Bean 的顺序。 3. **方案三 (@DependsOn)**:通过 `@DependsOn` 注解指定 Bean 之间的依赖关系,成功实现顺序控制,但耦合性较高。
实战指南:四种调整 Spring Bean 初始化顺序的方案
|
2月前
|
存储 运维 安全
Spring运维之boot项目多环境(yaml 多文件 proerties)及分组管理与开发控制
通过以上措施,可以保证Spring Boot项目的配置管理在专业水准上,并且易于维护和管理,符合搜索引擎收录标准。
52 2
|
2月前
|
前端开发 Java Spring
Spring MVC源码分析之DispatcherServlet#getHandlerAdapter方法
`DispatcherServlet`的 `getHandlerAdapter`方法是Spring MVC处理请求的核心部分之一。它通过遍历预定义的 `HandlerAdapter`列表,找到适用于当前处理器的适配器,并调用适配器执行具体的处理逻辑。理解这个方法有助于深入了解Spring MVC的工作机制和扩展点。
41 1
|
2月前
|
前端开发 Java Spring
Spring MVC源码分析之DispatcherServlet#getHandlerAdapter方法
`DispatcherServlet`的 `getHandlerAdapter`方法是Spring MVC处理请求的核心部分之一。它通过遍历预定义的 `HandlerAdapter`列表,找到适用于当前处理器的适配器,并调用适配器执行具体的处理逻辑。理解这个方法有助于深入了解Spring MVC的工作机制和扩展点。
37 1
|
2月前
|
前端开发 Java Spring
Spring MVC源码分析之DispatcherServlet#getHandlerAdapter方法
`DispatcherServlet`的 `getHandlerAdapter`方法是Spring MVC处理请求的核心部分之一。它通过遍历预定义的 `HandlerAdapter`列表,找到适用于当前处理器的适配器,并调用适配器执行具体的处理逻辑。理解这个方法有助于深入了解Spring MVC的工作机制和扩展点。
35 0
|
6月前
|
Java 测试技术 数据库
Spring Boot中的项目属性配置
本节课主要讲解了 Spring Boot 中如何在业务代码中读取相关配置,包括单一配置和多个配置项,在微服务中,这种情况非常常见,往往会有很多其他微服务需要调用,所以封装一个配置类来接收这些配置是个很好的处理方式。除此之外,例如数据库相关的连接参数等等,也可以放到一个配置类中,其他遇到类似的场景,都可以这么处理。最后介绍了开发环境和生产环境配置的快速切换方式,省去了项目部署时,诸多配置信息的修改。