接上篇点击查看
上篇分析到AbstractXmlApplicationContext的loadBeanDefinitions()方法
/**
* 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
*/
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);
}
}
进入AbstractBeanDefinitionReader类处理Resource[],或者String[](分别将String路径读取,解析成Resource[]),然后分别单独解析每个Resource资源,调用子类XmlBeanDefinitionReader的loadBeanDefinitions()方法,在loadBeanDefinitions这个类中,loadBeanDefinitions方法有四个重载的方法
当前调用的路径是loadBeanDefinitions(Resource)–>loadBeanDefinitions(EncodeResource)。剔除一些无关紧要的代码,关键代码就是图中红框选中的doLoadBeanDefinitions()方法
《可以看到,这种命名方式是很值得学习的,一种业务方法,比如parse(),可能需要做一些外围的工作,然后实际解析的方法,可以命名为doParse()。这种doXXX()的命名方法,在很多开源框架中都有应用,比如logback等》这段话来自慕课网的mark_rock的博文
继续往下走,可以看到剔除无关代码后,将Input流转换成标准的Document对象,然后调用registerBeanDefinitions()进行解析。
在registerBeanDefinitions()方法中,虽说名字上带有register。但并没有进入实际的解析和注册过程。而是创建一个DefaultBeanDefinitionDocumentReader(实现了接口BeanDefinitionDocumentReader )的实例,把解析和注册工作又委托给了BeanDefinitionDocumentReader
/**
* Register the bean definitions contained in the given DOM document.
* Called by {@code loadBeanDefinitions}.
* <p>Creates a new instance of the parser class and invokes
* {@code registerBeanDefinitions} on it.
* @param doc the DOM document
* @param resource the resource descriptor (for context information)
* @return the number of bean definitions found
* @throws BeanDefinitionStoreException in case of parsing errors
* @see #loadBeanDefinitions
* @see #setDocumentReaderClass
* @see BeanDefinitionDocumentReader#registerBeanDefinitions
*/
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
BeanDefinitionDocumentReader documentReader = BeanDefinitionDocumentReader.class.
cast(BeanUtils.instantiateClass(this.documentReaderClass));
///又委托给BeanDefinitionDocumentReader了
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
return getRegistry().getBeanDefinitionCount() - countBefore;
}
至此,终于开始进入正题了,在DefaultBeanDefinitionDocumentReader的解析和注册DOM对象。
在下篇博客中继续