首页 > 代码库 > BeanFactory not initialized or already closed exception

BeanFactory not initialized or already closed exception

启动spring 报错:
BeanFactory not initialized or already closed call ‘refresh‘ before accessing beans via the ApplicationContext


此错误是由AbstractRefreshableApplicationContext#getBeanFactory方法中抛出来的.
@Override
public final ConfigurableListableBeanFactory getBeanFactory() {
   synchronized (this.beanFactoryMonitor) {
      if (this.beanFactory == null) {
         throw new IllegalStateException("BeanFactory not initialized or already closed - " +
               "call ‘refresh‘ before accessing beans via the ApplicationContext");
      }
      return this.beanFactory;
   }
}

是因为在Spring在解析xml时出错, 导致close方法被调用, 而在close方法调用链上包括getBeanFactory.


详解:
方法一:
protected final void closeBeanFactory() {
   ...
   this.beanFactory = null;
}

方法二:
protected final void refreshBeanFactory() throws BeansException {
   ...
   closeBeanFactory();
   DefaultListableBeanFactory beanFactory = createBeanFactory();
   ...
   loadBeanDefinitions(beanFactory); // 加载bean定义(解析xml文件)
   ...
   this.beanFactory = beanFactory;
}

由方法一,二可知: 当加载bean定义(解析xml文件)出错时, AbstractRefreshableApplicationContext中的变量beanFactory为null.

方法三:
public void close() {
   ...
   doClose();
   ...
}
方法四:
protected void doClose() {
   ...
   destroyBeans();
   ...
}
方法五:
protected void destroyBeans() {
   getBeanFactory().destroySingletons();
}

由方法三,四,五可知: ApplicationContext的close方法被调用时,会调用getBeanFactory(), 这时beanFactory为null.


close最终是被ContextLoaderListener#contextDestroyed所调用.


BeanFactory not initialized or already closed exception