Spring Ioc創建之BeanFactory創建源碼分析

在上篇博客介紹了Ioc容器創建的大概過程,但BeanFactory創建的具體細節沒有說明,好!接下來就讓我們來看下BeanFactory創建的具體細節
首先我們來回顧一下前面內容中介紹過的AbstractApplicationContext中的方法refresh內部出現的一行代碼
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
接下來進入到方法obtainFreshBeanFactory中去看看具體實現(該方法的實現也是在AbstractApplicationContext中)

   protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        this.refreshBeanFactory();
        ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
        if(this.logger.isDebugEnabled()) {
            this.logger.debug("Bean factory for " + this.getDisplayName() + ": " + beanFactory);
        }

        return beanFactory;
    }

對於上面的代碼,Emphasis是在方法refreshBeanFactory上,那好!接下來來方法refreshBeanFactory

protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;

AbstractApplicationContext中的方法refreshBeanFactory()是個抽象方法,所以需要到繼承了AbstractApplicationContext類的子類中才有該方法的具體實現

這裏寫圖片描述

從上圖得知有兩個類·AbstractRefreshableApplicationContextGenericApplicationContext實現了抽象方法refreshBeanFactory()
接下來我們就進入到類·AbstractRefreshableApplicationContext,看看方法的具體實現,代碼如下:

protected final void refreshBeanFactory() throws BeansException {

       //如果存在BeanFactory對象,銷燬該對象,並重新創建BeanFactory
        if(this.hasBeanFactory()) {
            this.destroyBeans();
            this.closeBeanFactory();
        }

        try {
            DefaultListableBeanFactory beanFactory = this.createBeanFactory();
            beanFactory.setSerializationId(this.getId());
            this.customizeBeanFactory(beanFactory);

            //解析和登記Bean對象
            this.loadBeanDefinitions(beanFactory);

            Object var2 = this.beanFactoryMonitor;
            synchronized(this.beanFactoryMonitor) {
                this.beanFactory = beanFactory;
            }
        } catch (IOException var5) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5);
        }
    }

看上面的代碼中,我們看到創建了一個DefaultListableBeanFactory對象beanFactory, 具體過程見下面的代碼

protected DefaultListableBeanFactory createBeanFactory() {
        return new DefaultListableBeanFactory(this.getInternalParentBeanFactory());
    }

兩位有一個方法loadBeanDefinitions(beanFactory)也需要作爲重點分析下,在類AbstractRefreshableApplicationContext中該方法是個*抽象方法

protected abstract void loadBeanDefinitions(DefaultListableBeanFactory var1) throws BeansException, IOException;

下面的代碼是類AbstractXmlApplicationContext中的該方法loadBeanDefinitions(beanFactory)的實現代碼

  protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
        beanDefinitionReader.setEnvironment(this.getEnvironment());
        beanDefinitionReader.setResourceLoader(this);
        beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
        this.initBeanDefinitionReader(beanDefinitionReader);
        this.loadBeanDefinitions(beanDefinitionReader);
    }

在上面的代碼中看到下面所示兩個重要操作:

  • new XmlBeanDefinitionReader(beanFactory)
  • loadBeanDefinitions(beanDefinitionReader)

綜上所述:BeanFactory創建的詳細過程看下面的序列圖:
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章