從小白的角度看Spring核心流程概覽(XML版)- 容器初始化第三章-建立BeanFactory

本章咱們來看看Spring的BeanFactory是如何被建立的

一、方法概覽

入口:AbstractApplicationContext類refresh方法264行:
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();java

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		// 真正刷新BeanFactory的方法
        this.refreshBeanFactory();
		// 返回BeanFactory
        return this.getBeanFactory();
    }

2.一、刷新BeanFactory

//真正調用的是AbstractRefreshableApplicationContext的refreshBeanFactory方法
	protected final void refreshBeanFactory() throws BeansException {
		//判斷是否已經存在BeanFactory,若是存在就銷燬and關閉
        if(this.hasBeanFactory()) {
            this.destroyBeans();
            this.closeBeanFactory();
        }
        try {
			// 真正建立BeanFactory的方法
            DefaultListableBeanFactory beanFactory = this.createBeanFactory();
			// 給BeanFactory設置一個id,怎麼設置的本身看~
            beanFactory.setSerializationId(this.getId());
			// 定製BeanFactory
            this.customizeBeanFactory(beanFactory);
			// 加載Bean的Definition解析器
            this.loadBeanDefinitions(beanFactory);
			// 下面就是將建立出來的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);
        }
    }

2.1.一、建立BeanFactory

//AbstractRefreshableApplicationContext第103行
	protected DefaultListableBeanFactory createBeanFactory() {
		//建立並返回一個DefaultListableBeanFactory工廠,其中參數是他的父工廠
        return new DefaultListableBeanFactory(this.getInternalParentBeanFactory());
    }
	//AbstractApplicationContext第725行,這裏注意AbstractApplicationContext是AbstractRefreshableApplicationContext的父類,而這段邏輯對於全部上下文都管用,因此卸載這(後面這句話是我瞎猜的~)
	protected BeanFactory getInternalParentBeanFactory() {
		// 判斷當前上下文是否有父上下文,若是有就返回回去。固然這裏是沒有的,在Spring-MVC裏面的話就會有了~這樣看來工廠之間也有鏈路關係額。之前都不知道
        return (BeanFactory)(this.getParent() instanceof ConfigurableApplicationContext?((ConfigurableApplicationContext)this.getParent()).getBeanFactory():this.getParent());
    }

2.1.二、定製BeanFactory

//AbstractRefreshableApplicationContext第725行
	protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
		//若是 容許bean定義重寫 有值,則設置對於的值,這裏默認沒有,不過你要是使用事務的話,就會有了。
        if(this.allowBeanDefinitionOverriding != null) {
            beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding.booleanValue());
        }
		//若是 容許循環引用 有值,則設置對於的值,這裏默認也沒有。
        if(this.allowCircularReferences != null) {
            beanFactory.setAllowCircularReferences(this.allowCircularReferences.booleanValue());
        }

    }

2.1.三、加載DeFinition解析器

//這裏實際調用的是AbstractXmlApplicationContext的方法,若是你是Annotation版的,那麼走的就是Annotation版的了,到時候再說- -
	protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
		//建立一個XmlBeanDefinition的解析器
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
		// 設置系統屬性
        beanDefinitionReader.setEnvironment(this.getEnvironment());
		// 設置資源加載器
        beanDefinitionReader.setResourceLoader(this);
		// 設置實體解析器
        beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
		// 初始化BeanDefinitionReader解析器
        this.initBeanDefinitionReader(beanDefinitionReader);
		// 加載BeanDefinitions
		// 大內容,單獨分析
        this.loadBeanDefinitions(beanDefinitionReader);
    }

2.二、返回BeanFactory

//真正調用的是AbstractRefreshableApplicationContext的getBeanFactory方法
	//就是將上一步建立的BeanFactory返回回去。
	public final ConfigurableListableBeanFactory getBeanFactory() {
        Object var1 = this.beanFactoryMonitor;
        synchronized(this.beanFactoryMonitor) {
            if(this.beanFactory == null) {
                throw new IllegalStateException("BeanFactory not initialized or already closed - call 'refresh' before accessing beans via the ApplicationContext");
            } else {
                return this.beanFactory;
            }
        }
    }

總結

截至到如今,除了加載BeanDefinitions沒有講之外(實際上是我本身也還沒開始看....),BeanFactory的建立過程已經徹底結束。 首先spring會設置一堆亂七八糟的東西,而後定位在XML文件的位置,而且保存起來。這就是整個流程的第一步,資源定位。立刻咱們就要開始第二步,資源的加載了~下期見~spring

相關文章
相關標籤/搜索