Spring IOC啓動流程學習(一)

ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");

 

首先能夠看到ClassPathXmlApplicationContext繼承於BeanFactory和ResourceLoader兩個父類接口。java

咱們再來看ClassPathXmlApplicationContext的構造方法作了什麼ide

//調用了本身的另外一個構造方法
public ClassPathXmlApplicationContext(String... configLocations) throws BeansException {
   this(configLocations, true, null);
}
/**
調用了父類的構造方法,同時設置了配置文件的地址,並判斷是否刷新
**/
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
      throws BeansException {

   super(parent);
   setConfigLocations(configLocations);
   if (refresh) {
      refresh();
   }
}

 

跟進源碼裏面,super(parent),一直調用到了AbstractApplicationContext類post

/**
 * Create a new AbstractApplicationContext with the given parent context.
 * 第一次傳遞的parent爲null
 * @param parent the parent context
 */
public AbstractApplicationContext(ApplicationContext parent) {
   this();
   setParent(parent);
}

其中this()方法學習

/**
 * Create a new AbstractApplicationContext with no parent.
 * 獲取了一個資源解析器
 */
public AbstractApplicationContext() {
   this.resourcePatternResolver = getResourcePatternResolver();
}

因此在初始化的第一步就是設置了一個資源的解析器,讓咱們再回到第一步的初始化方法this

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
      throws BeansException {

/**
 * Create a new AbstractApplicationContext with no parent.
 * 獲取了一個資源解析器
 */
   super(parent);
/**
 * Create a new AbstractApplicationContext with no parent.
 * 設置配置文件的地址
 */
   setConfigLocations(configLocations);
/**
 * Create a new AbstractApplicationContext with no parent.
 * 重點在這個refresh方法
 */
   if (refresh) {
      refresh();
   }
}

refresh()方法是實現了ConfigurableApplicationContext接口的refresh方法,3d

進入refresh()方法內部code

@Override
public void refresh() throws BeansException, IllegalStateException {
 	// 首先加鎖,保證同一時間只會執行一個
   synchronized (this.startupShutdownMonitor) {
      // Prepare this context for refreshing.
      prepareRefresh();

      // Tell the subclass to refresh the internal bean factory.
      // 告訴子類刷新內部bean工廠,若是beanfactory已存在會先銷燬全部的bean,而後關閉beanfactory。而後建立beanfactory,加載beanDefinitions(bean定義)
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // Prepare the bean factory for use in this context.
      // 準備beanfactory供context使用
      prepareBeanFactory(beanFactory);

      try {
         // Allows post-processing of the bean factory in context subclasses.
         // 容許子類在context中的子類執行後置操做
         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.
         /// 初始化其餘特殊的bean
         onRefresh();

         // Check for listener beans and register them.
         // 註冊監聽者
         registerListeners();

         // Instantiate all remaining (non-lazy-init) singletons.
         // 初始化全部非lazy的單例bean
         finishBeanFactoryInitialization(beanFactory);

         // Last step: publish corresponding event.
         // 發送事件
         finishRefresh();
      }

      catch (BeansException ex) {
         if (logger.isWarnEnabled()) {
            logger.warn("Exception encountered during context initialization - " +
                  "cancelling refresh attempt: " + ex);
         }

         // Destroy already created singletons to avoid dangling resources.
         destroyBeans();

         // Reset 'active' flag.
         cancelRefresh(ex);

         // Propagate exception to caller.
         throw ex;
      }

      finally {
         // Reset common introspection caches in Spring's core, since we
         // might not ever need metadata for singleton beans anymore...
         resetCommonCaches();
      }
   }
}

refresh()方法沒有具體的展開,下次繼續學習bean的初始化部分。整個啓動的流程能夠簡單的總結一下爲如下流程。xml

相關文章
相關標籤/搜索