spring学习---IOC初始化顺序

目录

  • 说明
  • XMLBeanFactory详解
  • ClassPathXmlApplicationContext 详解
  • 源码分析

1. 说明:

IOC初始化顺序包括BeanDefinition的Resource 定位、载入和注册这三个基本过程。
容器主要有XmlBeanFactory、ClasspathXmlApplicationContext两种形式

2. XMLBeanFactory

2.1 继承图

spring学习---IOC初始化顺序

2.2 XmlBeanFactory源码

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

}

2.3 调用全过程 定位-载入-注册

//根据Xml 配置文件创建Resource 资源对象,该对象中包含了BeanDefinition 的信息
ClassPathResource resource = new ClassPathResource("application-context.xml");

//创建DefaultListableBeanFactory
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();

//创建XmlBeanDefinitionReader 读取器,用于载入BeanDefinition。之所以需要BeanFactory 
// 作为参数,是因为会将读取的信息回调配置给factory
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);

//XmlBeanDefinitionReader 执行载入BeanDefinition 的方法,最后会完成Bean 的载入和注册。
// 完成后Bean 就成功的放置到IOC 容器当中,以后我们就可以从中取得Bean 来使用
reader.loadBeanDefinitions(resource);

3. ClassPathXmlApplicationContext

3.1 继承图

spring学习---IOC初始化顺序

3.2 ClassPathXmlApplicationContext源码

public ClassPathXmlApplicationContext(String... configLocations) throws BeansException {
	this(configLocations, true, null);
}

public ClassPathXmlApplicationContext(
		String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
		throws BeansException {
    //设置资源加载器
	super(parent);
	//资源定位
	setConfigLocations(configLocations);
	if (refresh) {
		refresh();
	}
}

3.3 调用方式

public static void main(String[] args) {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
            "application.yml","application-jdbc.yml");
    context.getBean("userService");
}

4. 源码分析

//该构造方法完成了定位、载入、注册流程
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
            "application.yml","application-jdbc.yml");

4.1 流程图

主流程:

spring学习---IOC初始化顺序

BeanFactory中流程:

spring学习---IOC初始化顺序

加载beans流程

spring学习---IOC初始化顺序

具体解析并注入容器

spring学习---IOC初始化顺序

4.2 IOC调用的核心方法主线

类:ClassPathXmlApplicationContext

AbstractApplicationContext
	refresh()
		obtainFreshBeanFactory()
AbstractRefreshableApplicationContext
	refreshBeanFactory()	
AbstractXmlApplicationContext
	loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
		loadBeanDefinitions(beanDefinitionReader);
XmlBeanDefinitionReader
	loadBeanDefinitions(EncodedResource encodedResource)
		doLoadBeanDefinitions(inputSource, encodedResource.getResource())
			registerBeanDefinitions(doc, resource)
DefaultBeanDefinitionDocumentReader
	registerBeanDefinitions(Document doc, XmlReaderContext readerContext)
		doRegisterBeanDefinitions(Element root)
			parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate)
				processBeanDefinition(ele, delegate)
BeanDefinitionReaderUtils
	registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
DefaultListableBeanFactory
	registerBeanDefinition(String beanName, BeanDefinition beanDefinition)

4.3 IOC获取对象的核心方法主线

context.getBean("userService");
//方法主线
AbstractApplicationContext
	getBean(String name)
AbstractBeanFactory
	getBean(String name)
		doGetBean(name, null, null, false)
			createBean(beanName, mbd, args)
AbstractAutowireCapableBeanFactory
	 createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
		doCreateBean(beanName, mbdToUse, args)
			//将Bean实例对象封装,并且Bean定义中配置的属性值赋值给实例对象
			populateBean(beanName, mbd, instanceWrapper);