从小白的角度看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

相关文章
相关标签/搜索