spring 源码分析--IOC容器初始化一
IOC容器初始化
?
FileSystemXmlApplicationContext 包括一系列重载的构造方法。最后都会调用下面的方法:
===================================================================
/**
* 这里是IoC容器的初始化过程,其初始化过程的大致步骤由类
* AbstractApplicationContext来定义
*/
public FileSystemXmlApplicationContext(String[]configLocations, boolean refresh, ApplicationContext parent)
?????????? throws BeansException {
/**
* 调用父类构造函数,最终到类AbstractApplicationContext中执行下面代码:
* this.parent = parent;
*/
??? super(parent);
??? setConfigLocations(configLocations);
??? if (refresh) {
/**
* 这里是IoC容器的初始化过程,其初始化过程的大致步骤由类
* AbstractApplicationContext来定义
*/
?????? refresh();
??? }
}
===================================================================
public voidsetConfigLocations(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++) {
/**
* 该方法调用SystemPropertyUtils.resolvePlaceholders(path);对path中的占位符进行
*? 替换,eg:path路径中含有${user.dir},则将替换为:System.getProperty(user.dir);
*/
??????? ? this.configLocations[i] =resolvePath(locations[i]).trim();
??? ??? }
}else {
??? ??? this.configLocations = null;
===================================================================
public voidrefresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
/** 为refresh 做准备;*/
??? prepareRefresh();
/**
* 这里需要子类来协助完成资源位置定义,bean载入和向IOC容器注册的过程
*/
// 为当前上下文准备bean 工厂;
??? prepareBeanFactory(beanFactory);
try {
?????? // 允许在子类中对bean工厂做准备后的处理;
postProcessBeanFactory(beanFactory);
// 调用bean工厂处理上下文bean的注册;
?????? invokeBeanFactoryPostProcessors(beanFactory);
?????? // 注册bean创建拦截器的处理。
?????? registerBeanPostProcessors(beanFactory);
//?????? initMessageSource();
// 初始化上下文事件的 multicaster (多点播送;多路广播;多点传送).
initApplicationEventMulticaster();
// Initialize other special beans in specific contextsubclasses.
?????? onRefresh();
// Check for listener beans and register them.
?????? registerListeners();
// Instantiate all remaining(其余)(non-lazy-init) singletons.
?????? finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event. 发布相应的事件
?????? finishRefresh();
??? }catch (BeansException ex) {
?????? // Destroy already createdsingletons to avoid dangling resources.
?????? beanFactory.destroySingletons();
?????? // Reset 'active' flag.
?????? cancelRefresh(ex);
// Propagate exception to caller.
?????? throw ex;
?????? }
}
protected voidprepareRefresh() {
this.startupDate = System.currentTimeMillis();
??? ??? synchronized (this.activeMonitor) {
??? ??? this.active = true;?????
}
if (logger.isInfoEnabled()) {
??? ??? logger.info("Refreshing " + this);
}
/**
* 关闭前面所有bean 工厂,为新的上下文环境初始化一个新的bean工厂。这里需要子类来
* 协助完成资源位置定义,bean载入和向IOC容器注册的过程
*/
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
ConfigurableListableBeanFactorybeanFactory = getBeanFactory();
if (logger.isInfoEnabled()) {
logger.info("Bean factory for application context [" + getId() + "]: " +ObjectUtils.identityToString(beanFactory));
}
if (logger.isDebugEnabled()) {
logger.debug(beanFactory.getBeanDefinitionCount() + " beans defined in" + this);
}
return beanFactory;
/**
* 判断上下文是否还拥有bean工厂。return (this.beanFactory !=null);
*/
if (hasBeanFactory()) {
/**
* 清除当前上下文的所有bean,默认的实现为:清除当前上下文的所有缓存的单例bean,默认
* 的实现在父类:AbstractApplicationContext,
*/
destroyBeans();
//关闭bean工厂,代码:this.beanFactory = null;
closeBeanFactory();
}
try {
//创建一个bean工厂
??? DefaultListableBeanFactorybeanFactory = createBeanFactory();
/**? 制定bean工厂,即设置bean工厂的属性值,即:
*beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinit
*onOverriding.booleanValue());
*beanFactory.setAllowCircularReferences(this.allowCircularReference
*s.booleanValue());
*/
customizeBeanFactory(beanFactory);
/**
*给给定的bean工厂装载的bean定义,通常是通过委托给一个或多个*BeanDefinitionReader,在AbstractRefreshableApplicationContext类定义为抽*象函数,在
*AbstractXmlApplicationContext中定义了具体的实现。
*/
??? loadBeanDefinitions(beanFactory);
??? synchronized (this.beanFactoryMonitor) {
?????? this.beanFactory = beanFactory;
??? ??? }
??? }catch (IOException ex) {
?????? throw new ApplicationContextException(
"I/O error parsing XMLdocument for application context [" + getDisplayName() + "]", ex);
。提个小建议:能不能把代码高亮,这样看上去会舒服一点。 。
提个小建议:能不能把代码高亮,这样看上去会舒服一点。
我也觉得这个怎么看都不是很舒服,但是弄成代码格式超链接就没了?