IoC容器的启动过程

 <context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>applicationContext.xml</param-value>
 </context-param>
 
 <listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>

如上面web.xml的配置,IoC容器的启动由ContextLoaderListener这个监听器作为入口。

 public class ContextLoaderListener extends ContextLoader implements ServletContextListener {
    /**
      * Initialize the root web application context.
      */
     @Override
     public void contextInitialized(ServletContextEvent event) {
      initWebApplicationContext(event.getServletContext());
     }
 }

在init函数里调用父类ContextLoader的initWebApplicationContext方法完成webApplicationContext的创建和初始化。

140415_GFNw_1177710.png

protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc)  {
  //设置servletContext
  wac.setServletContext(sc);
  //配置文件的路径:applicationContext.xml
  String configLocationParam = sc.getInitParameter(CONFIG_LOCATION_PARAM);
  if (configLocationParam != null) {
   wac.setConfigLocation(configLocationParam);
  }
  // The wac environment's #initPropertySources will be called in any case when the context
  // is refreshed; do it eagerly here to ensure servlet property sources are in place for
  // use in any post-processing or initialization that occurs below prior to #refresh
  ConfigurableEnvironment env = wac.getEnvironment();
  if (env instanceof ConfigurableWebEnvironment) {
   ((ConfigurableWebEnvironment) env).initPropertySources(sc, null);
  }
  customizeContext(sc, wac);
  wac.refresh(); //IoC容器的加载过程都在这个函数里
}

140848_cjIG_1177710.png

 public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext{
        /**
          * This implementation performs an actual refresh of this context's underlying
          * bean factory, shutting down the previous bean factory (if any) and
          * initializing a fresh bean factory for the next phase of the context's lifecycle.
          */
         @Override
         protected final void refreshBeanFactory() throws BeansException {
          if (hasBeanFactory()) {
           destroyBeans();
           closeBeanFactory();
          }
          try {
           DefaultListableBeanFactory beanFactory = createBeanFactory();
           beanFactory.setSerializationId(getId());
           customizeBeanFactory(beanFactory);
           loadBeanDefinitions(beanFactory);  //加载bean的函数
           synchronized (this.beanFactoryMonitor) {
            this.beanFactory = beanFactory;
           }
          }
          catch (IOException ex) {
           throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
          }
         }
}

  bean的加载过程包括:

       1. 从来源处读取(载入);

       2. 解析,验证;

       3. 创建;

       4. 实例化及依赖对象的注入(如果bean的属性lazy-init设置true,那么此时不会有这个步骤,只有等到第一次用到该bean的时候才去做,及调用getBean时才实例化及依赖注入);

public class XmlWebApplicationContext extends AbstractRefreshableWebApplicationContext {

     /**
      * Loads the bean definitions via an XmlBeanDefinitionReader.
      * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
      * @see #initBeanDefinitionReader
      * @see #loadBeanDefinitions
      */
     @Override
     protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
      // Create a new XmlBeanDefinitionReader for the given BeanFactory.
      XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
      // Configure the bean definition reader with this context's
      // resource loading environment.
      beanDefinitionReader.setEnvironment(getEnvironment());
      beanDefinitionReader.setResourceLoader(this);
      beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
      // Allow a subclass to provide custom initialization of the reader,
      // then proceed with actually loading the bean definitions.
      initBeanDefinitionReader(beanDefinitionReader);
      loadBeanDefinitions(beanDefinitionReader);
     }
}
public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
    /**
      * Register the bean definitions contained in the given DOM document.
      * Called by {@code loadBeanDefinitions}.
      * <p>Creates a new instance of the parser class and invokes
      */
     public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
      BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
      documentReader.setEnvironment(this.getEnvironment());
      int countBefore = getRegistry().getBeanDefinitionCount();
      documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
      return getRegistry().getBeanDefinitionCount() - countBefore;
     }
}
public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocumentReader {
     @Override
     public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
      this.readerContext = readerContext;
      logger.debug("Loading bean definitions");
      Element root = doc.getDocumentElement();
      doRegisterBeanDefinitions(root);
     }
}

bean的信息是在BeanDefinition中定义的,解析出来的bean的信息是放在HashMap中存储的。

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
  implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
  
   /** Map of bean definition objects, keyed by bean name */
   private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(64);
   @Override
 public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
   throws BeanDefinitionStoreException {
        this.beanDefinitionMap.put(beanName, beanDefinition);
   }
  }

getBean是获取bean的地方,也是注入依赖的地方(递归调用)

public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
    @SuppressWarnings("unchecked")
     protected <T> T doGetBean(
       final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
       throws BeansException {
           // Guarantee initialization of beans that the current bean depends on.
            String[] dependsOn = mbd.getDependsOn();
            if (dependsOn != null) {
             for (String dependsOnBean : dependsOn) {
              if (isDependent(beanName, dependsOnBean)) {
               throw new BeanCreationException("Circular depends-on relationship between '" +
                 beanName + "' and '" + dependsOnBean + "'");
              }
              registerDependentBean(dependsOnBean, beanName);
              getBean(dependsOnBean);
             }
            }
       }
}

上面就是IoC容器加载过程中最重要的几个地方。

 

 

转载于:https://my.oschina.net/u/1177710/blog/414323

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值