@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