spring初始化中很重要的一步:
/**
* 刷新beanfactory,并解析配置文件,把配置文件中的bean一个个拿出来解析成bean定义,并且放到容器中去(并 *没有实例化,只是解析成bean定义)
* 重点:怎么把配置信息解析到
*/
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//我们单独看这个方法,先脑海中想象一下,返回值为beanFactory,那么beanFactory是干啥的,不是就是创建bean和管理bean嘛,接下来直接看源码
//org.springframework.context.support.AbstractApplicationContext#obtainFreshBeanFactory
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//刷新beanFactory和获取beanFactory
refreshBeanFactory();
return getBeanFactory();
}
// org.springframework.context.support.AbstractRefreshableApplicationContext#refreshBeanFactory
@Override
protected final void refreshBeanFactory() throws BeansException {
//判断beanFactory存不存在,如果存在,销毁bean和关闭beanFactory
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
//这里值得学习的地方就是我们看名字就知道是创建beanFactory设置id,加载bean定义
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
//加载bean定义
loadBeanDefinitions(beanFactory);
this.beanFactory = beanFactory;
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
//创建beanFactory的方法就是掉构造函数,直接看加载bean定义吧org.springframework.context.support.AbstractXmlApplicationContext#loadBeanDefinitions(org.springframework.beans.factory.support.DefaultListableBeanFactory)
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.
/**
* 我的理解为这里为初始化BeanDefinitionReader,然后用这个去加载BeanDefinition,并且放到容器中去
*/
initBeanDefinitionReader(beanDefinitionReader);
loadBeanDefinitions(beanDefinitionReader);
}
//org.springframework.context.support.AbstractXmlApplicationContext#loadBeanDefinitions(org.springframework.beans.factory.xml.XmlBeanDefinitionReader)
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
Resource[] configResources = getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
String[] configLocations = getConfigLocations();
if (configLocations != null) {
reader.loadBeanDefinitions(configLocations);
}
}
//本来考虑一步一步的调用链下去,但是发现调用链太过长,所以直接复制出调用链路,一步一步参考,大概就是用XmlBeanDefinitionReader解析
//org.springframework.beans.factory.support.AbstractBeanDefinitionReader#loadBeanDefinitions(java.lang.String...) ---> org.springframework.beans.factory.support.AbstractBeanDefinitionReader#loadBeanDefinitions(java.lang.String) ---> org.springframework.beans.factory.support.AbstractBeanDefinitionReader#loadBeanDefinitions(java.lang.String, java.util.Set<org.springframework.core.io.Resource>) ---> org.springframework.beans.factory.support.AbstractBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.Resource...) ---> org.springframework.beans.factory.xml.XmlBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.Resource) ---> org.springframework.beans.factory.xml.XmlBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.support.EncodedResource) ---> org.springframework.beans.factory.xml.XmlBeanDefinitionReader#doLoadBeanDefinitions---> org.springframework.beans.factory.xml.XmlBeanDefinitionReader#registerBeanDefinitions ---> org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#registerBeanDefinitions ---> org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#doRegisterBeanDefinitions ---> org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#parseBeanDefinitions ---> org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#parseDefaultElement ---> org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#processBeanDefinition
//至此:我们终于发现他要注册beanDefinition
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// Register the final decorated instance.
//最终注册bean定义,链路好长
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// Send registration event.
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
//org.springframework.beans.factory.support.BeanDefinitionReaderUtils#registerBeanDefinition
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// Register bean definition under primary name.
String beanName = definitionHolder.getBeanName();
//这里我们看到了beanDefinition终于放到了一个beanDefinitionMap的Map中去,我们也了解了我们的baen放到的容器其实就是一个map
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// Register aliases for bean name, if any.
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
看到这里,我们就知道beanDefinition是以map的形式存在容器中,具体怎么把配置文件解析成beanDefinition还需要细读源码