1.Spring IOC容器装载及注册bean的过程
ApplicationContext context = newClassPathXmlApplicationContext(
new String[] {"applicationContext-aop1.xml"});
其中ClassPathXmlApplicationContext继承抽象类AbstractApplicationContext
上面那行代码的通过调用ClassPathXmlApplicationContext的构造函数,调用AbstractApplicationContext的refresh()方法,实现IOC容器读取配置源数据,实例化,配置和组装bean。
由于Spring,每实例化一次ClassPathXmlApplicationContext,就会对应于一个beanFactory,也就是说一个IOC容器对应一个beanFactory,所以在IOC容器读取配置源数据,实例化,配置和组装bean前,要刷新beanFactory,并获取刷新后的beanFactory。
抽象类AbstractRefreshableApplicationContext继承抽象类AbstractApplicationContext,并实现AbstractApplicationContext的refreshBeanFactory()刷新beanFactory.
/**
* This implementation performs an actual refresh of this context's underlying
* bean factory, shutting down the previous bean factory (if any) and
* initializing a fresh bean factory for the next phase of the context's lifecycle.
*/
@Override
protectedfinalvoid refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
//创建一个DefaultListableBeanFactory的beanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
//这段代码是真正意义上的通过创建的beanFactory,读取源配置文件以及装载bean。
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
thrownew ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
从上面的代码可以看出,在创建beanFactory的时候,要判断是否已经存在beanFactory,如果存在就销毁,并关闭beanFactory。
抽象类AbstractXmlApplicationContext继承抽象类AbstractRefreshableApplicationContext,并实现loadBeanDefinitions()抽象方法。
/**
* Loads the bean definitions via an XmlBeanDefinitionReader.
* @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
* @see #initBeanDefinitionReader
* @see #loadBeanDefinitions
*/
@Override
protectedvoid 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);
//解析并装载bean
loadBeanDefinitions(beanDefinitionReader);
}
从loadBeanDefinitions()方法可以看出,Spring主要是通过XmlBeanDefinitionReader来解析源配置文件。
/**
* Load the bean definitions with the given XmlBeanDefinitionReader.
* <p>The lifecycle of the bean factory is handled by the {@link #refreshBeanFactory}
* method; hence this method is just supposed to load and/or register bean definitions.
* @param reader the XmlBeanDefinitionReader to use
* @throws BeansException in case of bean registration errors
* @throws IOException if the required XML document isn't found
* @see #refreshBeanFactory
* @see #getConfigLocations
* @see #getResources
* @see #getResourcePatternResolver
*/
protectedvoidloadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
Resource[] configResources = getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
String[] configLocations = getConfigLocations();
if (configLocations != null) {
reader.loadBeanDefinitions(configLocations);
}
}
调用XmlBeanDefinitionReader的子类AbstractBeanDefinitionReader的loadBeanDefinitions()方法
/**
* Load bean definitions from the specified resource location.
* <p>The location can also be a location pattern, provided that the
* ResourceLoader of this bean definition reader is a ResourcePatternResolver.
* @param location the resource location, to be loaded with the ResourceLoader
* (or ResourcePatternResolver) of this bean definition reader
* @param actualResources a Set to be filled with the actual Resource objects
<