1.BeanFactory
2.初始化的三个过程:Resource的定位,BeanDefinition的载入,向ioc容器注册这些BeanDefinitio。
Resource定位功能:
public class FileSystemXmlApplicationContext extends AbstractXmlApplicationContext
FileSystemXmlApplicationContext中都是构造方法。
public abstract class AbstractApplicationContext extends DefaultResourceLoader
关于IOC容器的相关功能的实现,都是在FileSystemXmlApplicationContext中完成的,在构造函数的中的refresh来启动。
//在对象初始化过程中,调用refresh函数载入BeanDefinition。
public FileSystemXmlApplicationContext(String[] configLocations,
boolean refresh,ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
//用于文件系统中的Resource的实现,通过构造一个FileSystemResource来得到一个在文件系统中定位的BeanDefinition
//getResourceByPath在BeanDefinitionReader的LoadBeanDefiniton中调用。
@Override
protected Resource getResourceByPath(String path) {
if (path != null && path.startsWith("/")) {
path = path.substring(1);
}
return new FileSystemResource(path);
}
getResourceByPath生成的是一个FileSystemResource对象,如果是其它的ApplicationContext会生成其它类型的Resource。
createBeanFactory创建了一个IOC容器供ApplicationContext使用,这个容器是DefaultListableBeanFactory,同时,他启动了loadBeanDefinition来载入BeanDefinition.
初始化FileSystmXmlApplicationContext的过程中,通过的方法就是refresh方法,使用的ioc容器是:DefultListableBeaFactory,具体的资源载入:AbstractBeanDefinitionReader中的loadBeanDefinitions实现资源的加载
@Override
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean
definition source for " + getDisplayName(), ex);
}
}
refresh()方法,AbstractApplicationContext
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
prepareRefresh();
//这边就有refreshBeanFactory的调用
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
prepareBeanFactory(beanFactory);
try {
postProcessBeanFactory(beanFactory);
invokeBeanFactoryPostProcessors(beanFactory);
registerBeanPostProcessors(beanFactory);
initMessageSource();
initApplicationEventMulticaster();
onRefresh();
registerListeners();
finishBeanFactoryInitialization(beanFactory);
finishRefresh();
}
catch (BeansException ex) {
destroyBeans();
cancelRefresh(ex);
throw ex;
}
}
}
BeanDefinition的载入和解析
载入的过程相当于是把BeanDefinition在IOC容器中转换成一个Spring内部表示的一个数据结构的过程.
载入的重点在于将资源转换成Spring能够认识的结构,相当于文件的解析,xml格式的比较的多。
注意下这个类:DefaultListableBeanFactory
.
.
AbstractRefreshableApplicationContext中有一个方法:refreshBeanFactory();来实例化一个BeanFactory的,在创建ioc容器之前,如果已经有容器存在了,就将已有的容器销毁和关闭。
这里的loadBeanDefinitions中,初始化读取器XmlBeanDefinitionReader,然后这个读取器在ioc容器中设置好,最后启动读取器来完成BeanDefinition在ioc容器中的载入。
//AbstractXmlApplicationContext
@Override
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);
}
经过逐层的解析,我们在XML中定义的BeanDefinition就被整个的载入到了IOC容器中去了,并在容器中建立了数据的映射,至此,IOC容器大致完成了管理Bean对象的数据准备,接着需要完成注册的过程。
BeanDefinition在IOC中的注册
HashMap结构.