@PostConstruct方法中含有ApplicationContext.getBean报错怎么办?


问题概述

想通过 @PostConstruct 实现一些 bean 初始化之后的逻辑,但同时注解的方法中有用到了一个静态类,类中使用如下伪代码:

private static final XxxBean XXX_BEAN = SpringContextUtils.getBean(XxxBean.class);

这就带来了一个问题,没法保证当前类初始化之前,XxxBean已经初始化完成了(当然可能有其他方式,这里不做赘述)。

解决方案

此时可以通过实现 ApplicationListener<ContextRefreshedEvent> 接口,并实现 onApplicationEvent 方法解决。

也就是在bean全部初始化完成之后,spring会自动调用这个方法。

示例代码如下:

@Component public class InitFinishNotice implements ApplicationListener<ContextRefreshedEvent> { @Override public void onApplicationEvent(ContextRefreshedEvent event) { // logic... } } 

二次调用问题

在传统 spring mvc 模式下,这里存在重复调用的问题,需要特殊一下。

打个断点,看一下 ContextRefreshedEvent 是什么?

  • org.springframework.context.event.ContextRefreshedEvent[source=Root WebApplicationContext, started on Tue Mar 09 13:44:10 CST 2021]
  • org.springframework.context.event.ContextRefreshedEvent[source=WebApplicationContext for namespace 'spring-servlet', started on Tue Mar 09 13:46:07 CST 2021, parent: Root WebApplicationContext]

第一次是Root WebApplicationContext,第二次是WebApplicationContext for namespace 'spring-servlet',它的父级是Root WebApplicationContext。所以可以通过 event.getApplicationContext().getParent() != null 区分一下,来避免重复调用。

示例代码如下:

@Component public class InitFinishNotice implements ApplicationListener<ContextRefreshedEvent> { @Override public void onApplicationEvent(ContextRefreshedEvent event) { if(event.getApplicationContext().getParent() != null){ return; } // logic... } } 

源码调用简述

  1. AbstractApplicationContext#refresh()
  2. finishRefresh();
  3. publishEvent(new ContextRefreshedEvent(this));
  4. getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
  5. SimpleApplicationEventMulticaster#multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType)
  6. for (ApplicationListener<?> listener : getApplicationListeners(event, type)) { invokeListener(listener, event)) }
  7. doInvokeListener(listener, event);

 

showtooltip


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM