容器启动过程总体流程
public void refresh() throws BeansException, IllegalStateException {
//容器在启动之前要获得对象锁,保证容器只有一个启动synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
      }
catch (BeansException ex) {
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset ‘active‘ flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
      }
   }
}第一个方法是prepareRefresh(),我们来看看这个方法具体都做什么了再总结下这个方法 
prepareRefresh() {
.= System.();
(.) {
.= ;
   }
(.isInfoEnabled()) {
.info(+ );
   }
   // 初始化上下文环境,容器的一些信息这个时候加载了进来比如  文件路径信息
initPropertySources();
//查看标示为必填的属性信息是否都有了
getEnvironment().validateRequiredProperties();
} 
prepareRefresh()只包含了两个方法,这两个方法加载了服务器的一些信息和判断必填项是否都完整。
第二个方法:ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
ConfigurableListableBeanFactory () {ConfigurableListableBeanFactory beanFactory = getBeanFactory();(.isDebugEnabled()) { .debug(+ getDisplayName() + + beanFactory); } beanFactory; }
refreshBeanFactory()这个方法比较复杂,做了很多我们平时忽略的事情,让我们仔细查看一下。
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
   //0-0   destroyBeans();
   //0-1   closeBeanFactory();
   }
try {//1
      DefaultListableBeanFactory beanFactory = createBeanFactory();//设置容器系列号,org.springframework.web.context.WebApplicationContext:
      beanFactory.setSerializationId(getId());
//2      customizeBeanFactory(beanFactory);
//3     loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
      }
   }
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
   }
}首先就是如果容器现在已经启动,而我们要新启动一个容器,那么首要的就是销毁以前的容器,具体过程如下 
//0-0
 destroyBeans();
protected void destroyBeans() {
   getBeanFactory().destroySingletons();
}
public void destroySingletons() {
if (logger.isInfoEnabled()) {
logger.info("Destroying singletons in " + this);
   }
synchronized (this.singletonObjects) {
this.singletonsCurrentlyInDestruction = true;
   }
   String[] disposableBeanNames;
synchronized (this.disposableBeans) {
      disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
   }
for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
      destroySingleton(disposableBeanNames[i]);
   }
this.containedBeanMap.clear();
this.dependentBeanMap.clear();
this.dependenciesForBeanMap.clear();
synchronized (this.singletonObjects) {
this.singletonObjects.clear();
this.singletonFactories.clear();
this.earlySingletonObjects.clear();
this.registeredSingletons.clear();
this.singletonsCurrentlyInDestruction = false;
   }
}这一个步骤就是清空容器和容器中注册了的bean。 
//0-1 
closeBeanFactory();
protected final void closeBeanFactory() {
synchronized (this.beanFactoryMonitor) {//对象序列号置空
this.beanFactory.setSerializationId(null);//对象释放
this.beanFactory = null;
   }
}新建容器对象  DefaultListableBeanFactory beanFactory = createBeanFactory();新建一个DefaultListableBeanFactory.注意在这里面有一个方法getInternalParentBeanFactory(),这个方法获得并设置了父容器。当然在spring启动的过程中这个父容器是空的。 
protected DefaultListableBeanFactory createBeanFactory() {
//
return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}步骤2主要是判断了一下三件事情 
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
//bean是否允许覆盖
if (this.allowBeanDefinitionOverriding != null) {
      beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
   }//bean是否允许循环引用
if (this.allowCircularReferences != null) {
      beanFactory.setAllowCircularReferences(this.allowCircularReferences);
   }//把java注解和spring标准注解都放到了容器里面来了
   beanFactory.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
}public void setAutowireCandidateResolver(final AutowireCandidateResolver autowireCandidateResolver) {
((BeanFactoryAware) autowireCandidateResolver).setBeanFactory(this);
this.autowireCandidateResolver = autowireCandidateResolver;
} 

步骤3要加载bean loadBeanDefinitions(beanFactory);我想这个过程应该是漫长而负责的。实现了该方法的类一共有三个1、XmlWebApplicationContext 2、AbstractXmlApplicationContext 3、AnnotationConfigWebApplicationContext.在项目启动的过程中XmlWebApplicationContext 真正的被执行。其余两个执行情况以后做研究。
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// 1 给指定工厂创建一个阅读器.
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
//.配置一个带有上下文资源环境的bean 定义阅读器,
beanDefinitionReader.setEnvironment(this.getEnvironment());
   beanDefinitionReader.setResourceLoader(this);
   beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
//允许子类个性初始化阅读器,程序可以实现接口XmlWebApplicationContext实现该方法实现个性化定制。initBeanDefinitionReader(beanDefinitionReader);
//加载beanDefinations
  loadBeanDefinitions(beanDefinitionReader);
}
loadBeanDefinitions(beanDefinitionReader);方法要加载bean的信息。 
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// 1 给指定工厂创建一个阅读器.
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
//.配置一个带有上下文资源环境的bean 定义阅读器,
beanDefinitionReader.setEnvironment(this.getEnvironment());
   beanDefinitionReader.setResourceLoader(this);
   beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
//允许子类个性初始化阅读器,程序可以实现接口XmlWebApplicationContext实现该方法实现个性化定制。initBeanDefinitionReader(beanDefinitionReader);
//加载beanDefinations
  loadBeanDefinitions(beanDefinitionReader);
}
loadBeanDefinitions(beanDefinitionReader);方法要加载bean的信息。 
原文:http://my.oschina.net/zjItLife/blog/527640