Spring的refresh()方法相关异常

如果是经常使用Spring,特别有自己新建ApplicationContext对象的经历的人,肯定见过这么几条异常消息:1.LifecycleProcessor not initialized – call ‘refresh’ before invoking lifecycle methods via the context: ……2.BeanFactory not initialized or already closed – call ‘refresh’ before accessing beans via the ApplicationContext3.ApplicationEventMulticaster not initialized – call ‘refresh’ before multicasting events via the context: ……第一条消息是说LifecycleProcessor对象没有初始化,在调用context的生命周期方法之前必须调用’refresh’方法第二条消息是说BeanFactory对象没有初始化或已经关闭了,使用ApplicationContext获取Bean之前必须调用’refresh’方法第三条消息是说ApplicationEventMulticaster对象没有初始化,在context广播事件之前必须调用’refresh’方法这几条异常消息都与refresh方法有关,那抛出这些异常的原因到底是什么,为什么在这么多情况下一定要先调用refresh方法(定义在AbstractApplicationContext类中),在此这前我们先看看refresh方法中又干了些什么?

public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {//刷新之前的准备工作,包括设置启动时间,是否激活标识位,初始化属性源(property source)配置prepareRefresh();//由子类去刷新BeanFactory(如果还没创建则创建),并将BeanFactory返回ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();//准备BeanFactory以供ApplicationContext使用prepareBeanFactory(beanFactory);try {//子类可通过格式此方法来对BeanFactory进行修改postProcessBeanFactory(beanFactory);//实例化并调用所有注册的BeanFactoryPostProcessor对象invokeBeanFactoryPostProcessors(beanFactory);//实例化并调用所有注册的BeanPostProcessor对象registerBeanPostProcessors(beanFactory);//初始化MessageSourceinitMessageSource();//初始化事件广播器initApplicationEventMulticaster();//子类覆盖此方法在刷新过程做额外工作onRefresh();//注册应用监听器ApplicationListenerregisterListeners();//实例化所有non-lazy-init beanfinishBeanFactoryInitialization(beanFactory);//刷新完成工作,包括初始化LifecycleProcessor,发布刷新完成事件等finishRefresh();}catch (BeansException ex) {// Destroy already created singletons to avoid dangling resources.destroyBeans();// Reset 'active' flag.cancelRefresh(ex);// Propagate exception to caller.throw ex;}}}与此三条异常消息相关的方法分别为:finishRefresh();obtainFreshBeanFactory();initApplicationEventMulticaster();

protected void finishRefresh() {// //初始化LifecycleProcessorinitLifecycleProcessor();// Propagate refresh to lifecycle processor first.getLifecycleProcessor().onRefresh();// Publish the final event.publishEvent(new ContextRefreshedEvent(this));// Participate in LiveBeansView MBean, if active.LiveBeansView.registerApplicationContext(this);}如果没有调用finishRefresh方法,则lifecycleProcessor成员为null。

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {refreshBeanFactory();//刷新BeanFactory,如果beanFactory为null,则创建ConfigurableListableBeanFactory beanFactory = getBeanFactory();if (logger.isDebugEnabled()) {logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);}return beanFactory;}refreshBeanFactory()为一抽象方法,真正实现在AbstractRefreshableApplicationContext类中:

@Overrideprotected final void refreshBeanFactory() throws BeansException {if (hasBeanFactory()) {//如果beanFactory已经不为null,则销毁beanFactory中的Bean后自行关闭destroyBeans();closeBeanFactory();}try {DefaultListableBeanFactory beanFactory = createBeanFactory();//创建beanFactorybeanFactory.setSerializationId(getId());customizeBeanFactory(beanFactory);loadBeanDefinitions(beanFactory);synchronized (this.beanFactoryMonitor) {this.beanFactory = beanFactory;//对beanFactory成员进行赋值}}catch (IOException ex) {throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);}}如果没有调用obtainFreshBeanFactory()方法则beanFactory成员为null。

protected void initApplicationEventMulticaster() {ConfigurableListableBeanFactory beanFactory = getBeanFactory();if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {this.applicationEventMulticaster =beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);if (logger.isDebugEnabled()) {logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");}}else {this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);if (logger.isDebugEnabled()) {logger.debug("Unable to locate ApplicationEventMulticaster with name '" +APPLICATION_EVENT_MULTICASTER_BEAN_NAME +"': using default [" + this.applicationEventMulticaster + "]");}}}而这三个方法调用都在refresh()方法中,由上面的分析可知,如果没有调用refresh方法,则上下文中的lifecycleProcessor,beanFactory,applicationEventMulticaster成员都会为null。至此可以来详细分析这三条异常消息的缘由了。下面是针对上面三条异常消息的三段测试代码,顺序相对应:

摘抄美文4、承诺是一件美好的事情,但美好的东西往往不会变为现实。

Spring的refresh()方法相关异常

相关文章:

你感兴趣的文章:

标签云: