转自http://www.sandzhang.com/blog/2011/04/02/spring-study-notes-initialization-2/
上篇结束的地方简单介绍了一下refresh()方法,现在我们具体分析一下它的代码细节:
1.首先可以看到整个refresh()的代码都是同步的,对应的同步对象是startupShutdownMonitor,我们看一下startupShutdownMonitor引用的地方,可以知道,只有在refresh()和close()两个方法里用到,说明这个锁是用来同步applicationContext的刷新和销毁的。
2.同步代码块的第一行是prepareRefresh()方法,代码如下:
protected void prepareRefresh() { this.startupDate = System.currentTimeMillis(); synchronized (this.activeMonitor) { this.active = true; } if (logger.isInfoEnabled()) { logger.info("Refreshing " + this); } }
这个方法也很简单
3.接着是这一行:ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(),obtainFreshBeanFactory代码如下:
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { refreshBeanFactory(); ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (logger.isDebugEnabled()) { logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory); } return beanFactory; }
第一行调用refreshBeanFactory(),我们先跳过这行看下面,调用了getBeanFactory()获得beanFactory对象然后返回这个对象,看getBeanFactory()的代码可以看到,是做了一个同步,然后取出当前对象里的beanFactory,同步锁是beanFactoryMonitor:
注:refreshBeanFactory()和getBeanFactory()方法在AbstractRefreshableApplicationContext类里面,关于ApplicationContext的类结构我会在另外一篇文章里做专门介绍,请看:ApplicationContext的类继承结构及框架图
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; } }
protected final void refreshBeanFactory() throws BeansException { if (hasBeanFactory()) { destroyBeans(); closeBeanFactory(); } try { DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId()); customizeBeanFactory(beanFactory); loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } }
前面3行代码首先判断是否hasBeanFactory(),如果存在则调用destroyBeans()以及closeBeanFactory():
接下来后面的代码是一个创建beanFactory的过程:
public void setSerializationId(String serializationId) { if (serializationId != null) { serializableFactories.put(serializationId, new WeakReference<DefaultListableBeanFactory>(this)); } else if (this.serializationId != null) { serializableFactories.remove(this.serializationId); } this.serializationId = serializationId; }
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) { if (this.allowBeanDefinitionOverriding != null) { beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding); } if (this.allowCircularReferences != null) { beanFactory.setAllowCircularReferences(this.allowCircularReferences); } beanFactory.setParameterNameDiscoverer(new LocalVariableTableParameterNameDiscoverer()); beanFactory.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver()); }
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); beanDefinitionReader.setResourceLoader(this); beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); initBeanDefinitionReader(beanDefinitionReader); loadBeanDefinitions(beanDefinitionReader); }