六、Spring MVC 源码学习(IOC 容器的初始化)

转载自:https://blog.csdn.net/lj1314ailj/article/details/80407753

一、体系结构

IOC 容器的初始化包括 BeanDefinition 的 Resource 定位、载入和注册这三个基本的过程。我们以 ApplicationContext 为例讲解来深入讲解,ApplicationContext系列容器也许是我们最熟悉的,因为 Web项目中使用的XmlWebApplicationContext就属于这个继承体系,还有
ClasspathXmlApplicationContext 等,其继承体系如下图所示:

这里写图片描述

二、职责分工

IOC容器初始化过程分为定位、载入、注册

定位是根据Resource来完成,

载入是根据BeanDefinitionReader,

剩下就是注册,注册是根据ListableBeanFactory。

下面我们分别简单地演示一下两种 IOC 容器的创建过程,一种是XmlBeanFactory 一种是FileSystemXmlApplicationContext 其中XmlBeanFactory已经被标记为过时的仅仅做简单讲述因为在Spring5.0中XmlBeanFactory已经被标记为过时的,为什么还要说呢!因为XmlBeanFactory相对纯粹也相对简单。

三、XmlBeanFactory IOC容器创建的流程

/**
 *DefaultListableBeanFactory 实现了BeanFactory所有子接口
 */
public class XmlBeanFactory extends DefaultListableBeanFactory {
	private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
	public XmlBeanFactory(Resource resource) throws BeansException {
		this(resource, null);
	}
	public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
		super(parentBeanFactory);
		this.reader.loadBeanDefinitions(resource);
	}
}

该类的依赖关系如下:

              

定位、载入、注册过程(一切以XmlBeanDefinitionReader 为核心(流程控制),XmlBeanFactory作为门面):

1.定位资源文件的位置(Resource)---------------------------------------------------------------------->定位

2.XmlBeanDefinitionReader读取Resource中的元数据,转为BeanDefinition------------------->加载                

3.将第二步的BeanDefinition注册到XmlBeanFactory--------------------------------------------------->注册

四、FileSystemXmlApplicationContext IOC容器创建的流程

ApplicationContext = new FileSystemXmlApplicationContext(xmlPath);

其实际调用的构造函数为:

public FileSystemXmlApplicationContext(
        String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
        throws BeansException {
    super(parent);
    setConfigLocations(configLocations);
    if (refresh) {
        refresh();
    }
}

分析:

1.super(parent)  //父类初始化资源加载器

2.setConfigLocations  //根据Environment替换路径中的placeHolder字符串

3.refresh()//Bean定义资源的载入是从refresh()函数开始的,refresh()是一个模板方法,refresh()方法的作用是:在创建 IOC 容器前,如果已经有容器存在,则需要把已有的容器销毁和关闭,以保证在 refresh 之后使用的是新建立起来的 IOC 容器。refresh 的作用类似于对 IOC容器的重启。

refresh调用关系如下图:

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
		// Create a new XmlBeanDefinitionReader for the given BeanFactory.
		XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

		// Configure the bean definition reader with this context's
		// resource loading environment.
		beanDefinitionReader.setEnvironment(this.getEnvironment());
		beanDefinitionReader.setResourceLoader(this);
		beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

		// Allow a subclass to provide custom initialization of the reader,
		// then proceed with actually loading the bean definitions.
		initBeanDefinitionReader(beanDefinitionReader);
		loadBeanDefinitions(beanDefinitionReader);
	}
//被上个方法最后一行调用
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
		Resource[] configResources = getConfigResources();
		if (configResources != null) {
			reader.loadBeanDefinitions(configResources);
		}
		String[] configLocations = getConfigLocations();
		if (configLocations != null) {
			reader.loadBeanDefinitions(configLocations);
		}
	}

问题:

        XmlBeanDeafineReader如何加载资源?

总结(类职责):

         (以下分析,从上往下看,父子类关系)

         1.FileSystemXmlApplicationContext  

                                        主流程调度(1.父容器构建  2.配置文件文件路径处理 3.刷新容器)

         2.AbstractXmlApplicationContext  

                                       核心流程调度(XmlBeanDefinitionReader 初始化及加载)

        3.AbstractRefreshableConfigApplicationContext

                                       增加成员变量(用于配置文件)

                                       路径中特殊符号的处理,多路径分割处理

        4.AbstractRefreshableApplicationContext

                                       刷新bean工厂(清空之前的工厂,重新加载工厂)

        5.AbstractApplicationContext

                                       bean的初始化的前置、后置处理等核心业务逻辑()

                                      

          

猜你喜欢

转载自blog.csdn.net/qq2413273056/article/details/82594059