Spring中ApplicationContext初始化過程

Spring在初始化過程中要做的事情很多,下面我們就根據(jù)ClassPathXmlApplicationContext初始化看看我們的應(yīng)用走了哪些步驟,我用debug模式下一步步來展現(xiàn)初始化過程。
首先我們看一下ClassPathXmlApplicationContext類的繼承關(guān)系

ClassPathXmlApplicationContext
AbstractXmlApplicationContext
AbstractRefreshableConfigApplicationContext
AbstractRefreshableApplicationContext
AbstractApplicationContext
DefaultResourceLoader
I ResourceLoad
ApplicationContext context = new ClassPathXmlApplicationContext("conf/applicationContext.xml");
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
            throws BeansException {
        super(parent);
        setConfigLocations(configLocations);
        if (refresh) {
            refresh();
        }
    }

初始化應(yīng)用上下文,使用ClassPathXmlApplicationContext類新建實(shí)例,初始化這個類,我們可以看到使用super方法初始化了父類,上面繼承樹中所有的類都初始化了;然后把傳送的配置文件目錄設(shè)置為配置文件;調(diào)用refresh方法,這個方法是AbstractApplicationContext類實(shí)現(xiàn)的方法。

public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
//準(zhǔn)備上下文的刷新,
            prepareRefresh();
            // Tell the subclass to refresh the internal bean factory.
//得到新的Bean工廠,應(yīng)用上下文加載bean就是在這里面實(shí)現(xiàn)的
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//準(zhǔn)備bean工廠用在上下文中
            // Prepare the bean factory for use in this context.
            prepareBeanFactory(beanFactory);
            try {
                // Allows post-processing of the bean factory in context subclasses.
//允許子類上下問處理bean工廠
                postProcessBeanFactory(beanFactory);
                // Invoke factory processors registered as beans in the context.
//請求工廠處理器作為beans注冊在上下文
                invokeBeanFactoryPostProcessors(beanFactory);
                // Register bean processors that intercept bean creation.
//注冊bean處理器攔截bean創(chuàng)建
                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.
//檢查監(jiān)聽bean并注冊
                registerListeners();
                // Instantiate all remaining (non-lazy-init) singletons.
//實(shí)例化未初始化單例
                finishBeanFactoryInitialization(beanFactory);
                // Last step: publish corresponding event.
//最后一步發(fā)布相應(yīng)事件
                finishRefresh();
            }

obtainFreshBeanFactory方法把配置文件中的bean加載到容器中。調(diào)用AbstractRefreshableApplicationContext的refreshBeanFactory方法,然后調(diào)用loadBeanDefinitioans(beanFactory)方法,這個方法的實(shí)現(xiàn)類是XmlWebApplicationContext的loadBeanDefinitions方法,方法調(diào)用Reader中的loadBeanDefinitions(configLocations)把配置文件傳入Reader。

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
//這里定義了Reader來讀取Bean,在loadBeanDifinitions方法中傳入reader
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
......
        // then proceed with actually loading the bean definitions.
        initBeanDefinitionReader(beanDefinitionReader);
        loadBeanDefinitions(beanDefinitionReader);
    }

XmlBeanDefinitionReader中調(diào)用AbstractBeanDefinition中的loadBeanDefinitions(location)方法。把配置文件讀取成Resource后,調(diào)用XmlBeanDefinitionReader中loadBeanDefinitions(Resource)方法,在方法中調(diào)用doLoadBeanDefinitions(InputSource inputSource, Resource resource)傳入?yún)?shù)是文件流和Resource,方法內(nèi)調(diào)用registerBeanDefinitions(Document doc,Resource resource)方法

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;
    }

在DocumentReader調(diào)用注冊bean方法中進(jìn)行注冊,調(diào)用DefaultBeanDefinitionDocumentReader的doRegisterBeanDefinitions方法,在parseBeanDefinitions方法中調(diào)用parseDefaultElement(ele, delegate);方法,判斷如果獲取到的是個bean的話執(zhí)行,processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate)方法最后在DefaultListableBeanFactory類中調(diào)用registerBeanDefinition進(jìn)行注冊,注冊的容器是this.beanDefinitionMap.put(beanName, beanDefinition);,這個是初始化的CurrentHashMap類。
容器的初始化以及Bean的注冊就完成了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容