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的创建和初始化。

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容器的加载过程都在这个函数里
}

 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容器加载过程中最重要的几个地方。

时间: 2024-10-10 09:42:37

IoC容器的启动过程的相关文章

SpringBoot:Spring容器的启动过程

一.简述 Spring的启动过程就是IoC容器的启动过程,本质上就是创建和初始化Bean的工厂(BeanFactory),BeanFactory是整个SpringIoC的核心,Spring使用BeanFactory来实例化.配置和管理Bean. 二.SpringBoot的启动过程 在SpringBoot中,SpringApplication封装了一套Spring应用的启动流程,对用户完全是透明的,这个类原本在Spring中是没有的. 一般来说,默认的SpringApplication执行流程可以

SpringBoot启动流程分析(四):IoC容器的初始化过程

SpringBoot系列文章简介 SpringBoot源码阅读辅助篇: Spring IoC容器与应用上下文的设计与实现 SpringBoot启动流程源码分析: SpringBoot启动流程分析(一):SpringApplication类初始化过程 SpringBoot启动流程分析(二):SpringApplication的run方法 SpringBoot启动流程分析(三):SpringApplication的run方法之prepareContext()方法 SpringBoot启动流程分析(四

Spring IoC容器的初始化过程

Spring IoC容器的初始化包括 BeanDefinition的Resource定位.载入和注册 这三个基本的过程.IoC容器的初始化过程不包含Bean依赖注入的实现.Bean依赖的注入一般会发生在第一次通过getBean向容器索取Bean的时候. 先看以下代码: ApplicationContext context = new ClassPathXmlApplicationContext("ioc.xml"); Car car = (Car) context.getBean(&q

IOC容器的初始化过程

1.ClassPathXmlApplicationContext类体系结构 左边的黄色部分是ApplicationContext体系继承结构,右边是BeanFactory结构体系,两个体系是典型的模板方法设计模式的使用. 从该继承体系可以看出: (1)BeanFactory是一个bean工厂的最基本定义,里面包含了一个bean工厂的几个最基本方法:getBean(),containsBean()等,是一个很纯粹的bean工厂,不关注资源.资源位置.事件等. ApplicationContext是

spring容器的启动过程(1)

容器启动过程总体流程 public void refresh() throws BeansException, IllegalStateException { //容器在启动之前要获得对象锁,保证容器只有一个启动synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh(); // Tell the subclass to refresh the inter

Java Web容器的启动过程

Java web容器的启动与处理请求的过程 1.启动一个web项目的时候,web容器回去读取它的配置文件web.xml,读取<Context-param>结点. 2.容器创建一个servletContext(Servlet上下文),这个web项目的所有部分都将共享这个上下文. 3.容器将<context-param>转换为键值对,并交个ServletContext.因为listener,filter等组件在初始化时会用到这些上下文的信息,所以要先加载. 4.容器创建<list

spring的启动过程就是创建ioc容器的过程

1. spring简介 spring的最基本的功能就是创建对象及管理这些对象之间的依赖关系,实现低耦合.高内聚.还提供像通用日志记录.性能统计.安全控制.异常处理等面向切面的能力,还能帮我们管理最头疼的数据库事务,本身提供了一套简单的JDBC访问实现,提供与 第三方数据访问框架集成(如hibernate.JPA),与各种Java EE技术整合(如JavaMail.任务调度等等),提供一套自己的web层框架Spring MVC.而且还能非常简单的与第三方web框架集成.从这里我们可以认为Sprin

Spring 源码学习(二) IOC容器启动过程

这一节主要是记录一下Spring Ioc 容器的启动过程. Spring 的 Ioc 容器是怎么被加载和使用的? web容器为它提供了宿主环境 ServlectContext,  Tomcat 启动时会读取web.xml. 并且实例化web.xml中配置的ContextLoaderListener ,下面看一下ContextLoaderListener的创建过程: 在实例化ContextLoaderListener 之后,通过接口回调执行ContextLoaderListener 类中的cont

好记性不如烂笔头83-spring3学习(4)-spring的BeanFactory(IoC容器)

我们一般把BeanFactory叫做IoC容器,叫ApplicationContext 为应用上下文(或者Spring容器) BeanFactory是spring框架的核心,实现依赖注入[使个组件的依赖关系从代码中独立出来,使用配置文件即可实现这种依赖关系]和bean声明周期的管理 . BeanFactory[IoC容器]启动过程:分为两个阶段,一个是容器启动阶段,另外一个是Bean实例化阶段 容器启动阶段:加载配置 -–> 分析配置信息 -–>装备到BeanDefinition -–>