Spring源码之ApplicationContext(一)

相信读者对于ApplicationContext方式加载 XML的使用并不陌生。例如:

ApplicationContext ac = newClassPathXmlApplicationContext(“beans.xml”).从这一节开始笔者将会围绕着ApplicationContext的加载XML文件的使用来讲解Spring源码。首先我们以ClassPathXmlApplicationContext类作为切入点。

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

		super(parent);
		<strong>setConfigLocations(configLocations)</strong>;
		if (refresh) {
			<strong>refresh()</strong>;
		}
	}
上面的方法中,首先执行的是setConfigLocations()的方法,这个方法主是支持多个配置文件以数组方式同时传入。

public void setConfigLocations(String... locations) {
		if (locations != null) {
			Assert.noNullElements(locations, "Config locations must not be null");
			this.configLocations = new String[locations.length];
			for (int i = 0; i < locations.length; i++) {
				//解析给定路径
				this.configLocations[i] = resolvePath(locations[i]).trim();
			}
		}
		else {
			this.configLocations = null;
		}
	}

其次,我们来看一下refresh()的方法,这个函数几乎包含了ApplicationContext中提供的全部功能。

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			<strong>prepareRefresh();</strong>

			// Tell the subclass to refresh the internal bean factory.
			//初始化BeanFactory,并进行XML文件读取
			ConfigurableListableBeanFactory beanFactory = <strong>obtainFreshBeanFactory()</strong>;

			// Prepare the bean factory for use in this context.
			//对BeanFactory进行各种功能填充
			<strong>prepareBeanFactory(beanFactory)</strong>;

			try {
				// Allows post-processing of the bean factory in context subclasses.
				//子类覆盖方法做额外的处理
				<strong>postProcessBeanFactory(beanFactory)</strong>;

				// Invoke factory processors registered as beans in the context.
				//激活各种BeanFactory处理器
				<strong>invokeBeanFactoryPostProcessors(beanFactory)</strong>;

				// Register bean processors that intercept bean creation.
				//注册拦截Bean创建的Bean处理器,这里只是注册,真正的调用是在getBean时候
				<strong>registerBeanPostProcessors(beanFactory)</strong>;

				// Initialize message source for this context.
				//为上下文初始化Message源,即不同语言的消息体,国际化处理
				<strong>initMessageSource()</strong>;

				// Initialize event multicaster for this context.
				//初始化应用消息广播器,并放入“applicationEventMulticaster”bean中
				<strong>initApplicationEventMulticaster()</strong>;

				// Initialize other special beans in specific context subclasses.
				//留给子类来初始化其它的Bean
				<strong>onRefresh()</strong>;

				// Check for listener beans and register them.
				//在所有注册bean中查找Listener bean,注册到消息广播器中
				<strong>registerListeners()</strong>;

				// Instantiate all remaining (non-lazy-init) singletons.
				//初始化剩下的单例实例(非惰性的)
				<strong>finishBeanFactoryInitialization(beanFactory)</strong>;

				// Last step: publish corresponding event.
				//完成刷新过程,通过生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人
				<strong>finishRefresh()</strong>;
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				<strong>destroyBeans()</strong>;

				// Reset 'active' flag.
				<strong>cancelRefresh(ex)</strong>;

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
			}
		}
	}

这里笔者对上面的方法进行以下的概括:

1)        初始化前的准备工作,例如对系统属性或者环境进行准备及验证。

2)        初始化BeanFactory,并进行XML文件读取。

3)        对BeanFactory进行各种功能填充。

4)        子类覆盖方法做额外的处理。

5)        激活各种BeanFactory处理器。

6)        注册拦截bean创建的bean处理器,这里只是注册,真正的调用是在getBean时候。

7)        为上下文初始化Message源,即对不同语言的消息体进行国际化处理。

8)        初始化应用消息广播器,并放入“applicationEventMulticaster”bean中。

9)        留给子类来初始化其他的bean。

10)    在所有注册的bean中查找listenerbean,注册到消息广播器中。

11)    初始化剩下的单例(非惰性)

12)    完成刷新过程,通知生命周期处理器lifecycleProcessor刷新过程,同时发出ContextRefreshEvent通知别人。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值