死磕Spring原理--ClasspathXmlApplicationContext加载bean过程

执行ClasspathXmlApplicationContext构造器,最终会执行到下面这个方法

Tips:大部分spring的代码中,xxx()并不是实际工作的方法,而doXxx()才是。

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)throws BeansException {

		super(parent);
		setConfigLocations(configLocations);
		if (refresh) {
			refresh();
		}
	}

super(parent):执行父类构造器,parent是null,最终会按顺序执行下面4个类的构造

AbstractXmlApplicationContext->
AbstractRefreshableConfigApplicationContext->
AbstractRefreshableApplicationContext->
AbstractApplicationContext

setConfiglocation():把传入的配置文件路径解析

refresh():核心方法,实际调用的是 AbstractApplicationContext类中的refresh()方法。

refresh()解析

其中总共有15个步骤,除开catch的部分的步骤,有以下的操作

public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
	// 1. 准备计时,初始化各种状态标记,验证环境配置
	prepareRefresh();
	// 2. 创建工厂,加载BeanDefinition,这里包括xml中写入配置,以及spring核心的一些bean,例如监听器。
	ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
	// 3. 初始化工厂设置
	prepareBeanFactory(beanFactory);
	try {
		// 4. 允许工厂上下文中的后置处理器		
		postProcessBeanFactory(beanFactory);
		// 5. 调用工厂后置处理器 -- 如扫描包
		invokeBeanFactoryPostProcessors(beanFactory);
		// 6. 注册Bean的后置处理器
		registerBeanPostProcessors(beanFactory);
		// 7. 为上下文初始化消息源
		initMessageSource();
		// 8. 为上下文初始化事件广播器 -- spring内部的事件机制
		initApplicationEventMulticaster();
		// 9. 初始化其他特定的其他Bean -- 这里也是一个空方法
		onRefresh();
		// 10. 注册监听器
		registerListeners();
		// 11. 完成其他剩余的单例的bean,这是注入开始的地方
		finishBeanFactoryInitialization(beanFactory);
		// 12. 发布相应事件,完成refresh
		finishRefresh();
	}catch{
		...
	}
	finally {
		//15. 清除一些缓存
		resetCommonCaches();
	}
}

第2步中,会执行到AbstractRefreshableApplicationContext类中的refreshBeanFactory(),其中的关键步骤loadBeanDefinitions(beanFactory),是负责加载BeanDefinition的。

这个方法又走到了AbstractXmlApplicationContext中,

@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
	// 创建xml beanDefinition读取器
	XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

	// 配置读取器环境,资源加载器,解析器
	beanDefinitionReader.setEnvironment(this.getEnvironment());
	beanDefinitionReader.setResourceLoader(this);
	beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

	//初始化读取器,加载BeanDefinition
	initBeanDefinitionReader(beanDefinitionReader);
	loadBeanDefinitions(beanDefinitionReader);
}

其中最后loadBeanDefinitions(beanDefinitionReader)又是关键。一直跟进代码,主要以loadBeanDefinition关键字去跳转,追踪路径。

最终会找到DefaultBeanDefinitionDocumentReader类中的doRegisterBeanDefinitions方法。

...
//这就是解析xml,并把xml中的bean加载进来的方法
parseBeanDefinitions(root, this.delegate);
...

跟进到这里,会对xml进行解析,最终走进processBeanDefinition方法,在这个方法里,最终把BeanDefinition进行注册。

从这一些列步骤跳出,完成了BeanFactory的初步创建,创建工厂本身和加载xml中的bean。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值