持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第5天,点击查看活动详情
一次项目启动阶段无法获取bean的问题
前文
首先进行一下问题过程的描述。项目采用springboot搭建,利用@postConstruct进行启动阶段预加载。由于在操作过程中需要根据一定的规则进行对象的动态加载,而在动态加载时在某些情况下需要进行redis的相关操作,因此在新增的对象中选择利用spring上下文进行redis相关bean对象的获取。而在获取的过程中,出现了bean对象空指针的问题,也就是加载该代码时,并未实现bean对象的完全初始化。
代码内容及解决方案
根据上述的问题,首先看一下原始的代码。
启动阶段首先进行预加载初始化的设置:
@PostConstruct
public void init(){
logger.info("程序启动进行规则链加载");
chainService.initChain();
}
而在具体的执行方法中,则进行相关对象的动态初始化,主要采用反射实现:
o = (ChainHandler)cons.newInstance(chainDTO.getDetailJsons().get(j),ruleId,nodeId);
而实际我们所创建出来的ChainHandler对象,则需要通过上下文进行bean获取,再进行相应的redis操作:
this.multiTenantRedisUtils = ApplicationContextUtil.getBean(MultiTenantRedisUtils.class);
那么分析一下问题的原因,其实该问题的出现主要就是由于我们是在初始化阶段就需要通过bean上下文进行对象的获取,而也正是依然处于初始化阶段,使得bean对象此时尚未完全创建成功。经过断点分析,可以很轻易的发现此时很多实际需要应用的bean依然为空值。相应的,也就很容易想到解决办法,我们需要在初始化阶段,当进行bean获取前,事先指定该bean需要被创建。那么具体该如何处理,这里采用在初始化阶段所调用的bean对象chainService。我们在chainService中进行redis相关内容的导入,则可以确保当初始化阶段实际的逻辑执行时,需要的bean已经被预先注入到管理器中,也就能够避免获取不到的问题导致的空指针异常。
@Autowired
MultiTenantRedisUtils multiTenantRedisUtils;
后记
- 千古兴亡多少事?悠悠。不尽长江滚滚流。