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