mongoTemplate无法被自动注入问题及解决方案

2019-04-26 02:34:50  晓掌柜  版权声明:本文为站长原创文章,转载请写明出处


一、背景


       今天在调用XX接口时,需要把返回数据存放到mongoDB中,但是在进行mongoTemplate.save(obj);时报空指针异常。

    这个问题同样出现了在了我Dubbo中使用工厂模式的项目中了,所以时隔三年之后对该文章进行重新编辑。

二、问题出现场景


    2.1、静态方法注入

        静态方法中注入静态变量为null

    2.2、测试类注入

        在测试方法中new一个service类然后发现在service中的bean注入为null (网上有相应通过配置解决的方案)

    2.3、工厂模式注入

        DUBBO项目工厂类使用Autowire注入工具类为null


三、解决方案


    ① 先使用@Component来注入服务

    ② 然后再使用@Autowire来注入service的Bean

    ③ 使用@PostConstruct注解,他可以在加载servlet时运行一次然后我们把service的Bean对象储存下来


四、相关释义


    1、@Componnet:一般来说当我们的类(泛指各种组件)不属于@Controller、@Service等,但是我们又想把他

        加入到我们的应用中的时候,我们就可以直接在类上面用次注解(Bean是修饰方法的)。

    2、@PostConstruct:用来修饰一个费静态的void()方法,在Bean创建完成后会默认执行@PostConstruct修饰的方法。

        Bean加载 -> @Autowire注入 -> 执行@PostConstruct修饰的方法


五、附上关键代码段

    @Component

public class PolicysyncService {

@Autowired
private MongoTemplate mongoTemplate;

private static PolicysyncService policysyncService;

@PostConstruct
public void init() {
policysyncService = this;
policysyncService.mongoTemplate = this.mongoTemplate; /* 后面既可以使用policysyncService.mongoTemplate来进行操作 */ }
}


六、代码段示例及解析


    6.1、场景复现

        ① 我在项目中定义了一个Common子项目,里面放置了一个RabbitMq的工具类RabbitUtil

        ② 在Dubbo中的生产者中的其中的工厂方法OrderDataCollectAndAnalyseApiServiceImpl使用Autowire注入为null

    6.2、解决方案

        ① 先声明一个静态私有类:OrderDataCollectAndAnalyseApiServiceImpl

        ② 使用@PostConstruct注解声明一个init方法

        ③ 项目加载时会把RabbitUtil进行初始化

        ④ 使用orderDataCollectAndAnalyseApiService.rabbitUtil进行业务操作

    6.3、代码段示例


/**
* @author XA
* date 2021/5/31 11:58
* description: 数据采集分析接口实现类
**/
@Service
public class OrderDataCollectAndAnalyseApiServiceImpl extends ServiceImpl<SysDataCollectAndAnalyseDao, SysDataCollectAndAnalyseEntity>
implements SysDataCollectAndAnalyseApi{

@Autowired
private RabbitUtil rabbitUtil;

@Autowired
private RedisMsgUtil redisMsgUtil;

private static OrderDataCollectAndAnalyseApiServiceImpl orderDataCollectAndAnalyseApiService;
@PostConstruct
public void init(){
orderDataCollectAndAnalyseApiService = this;
orderDataCollectAndAnalyseApiService.rabbitUtil = this.rabbitUtil;
}

/**
* 功能描述: 数据采集
* Param: [ dataId, step]
* Return: com.bh.modules.commons.param.R
*/
@Override
public R analyseDataSave(Long dataId, Integer step, String params, Long userId) {
try {
SysDataCollectAndAnalyseEntity sysDataCollectAndAnalyseEntity =
new BuildAnalyseDTO().orderDtoHandle(SysDataAnalyseTypeEnum.STATE_00.getKey(), dataId, step, userId,1, params);
/* 写入mq */
orderDataCollectAndAnalyseApiService.rabbitUtil.sendOrderDataAnalyseMessage(JSONObject.toJSONString(sysDataCollectAndAnalyseEntity));
return R.ok();
}catch (Exception e){
/* 发送失败 写入缓存 */
Map<String, Object> map = new HashMap<>();
map.put("dataId", dataId);
map.put("step", step);
map.put("params", params);
map.put("userId", userId);
map.put("dateTime", LocalDateTime.now().toString());
redisMsgUtil.saveRabbitMsgToCache(JSONObject.toJSONString(map));
return R.error(e.getMessage());
}
}

    6.4、实际运行场景

    


    更多精彩请持续关注:guangmuhua.com


最新评论:

跑不了,是错的
2020-08-23 18:04:18
1楼
2020-08-23 18:02:20
2楼
啥,啥,啥,这都是些啥
2019-04-28 12:59:00
3楼