以xml文件方式定義的bean爲例,XmlBeanDefinitionReader 是xml形式的bean 定義讀取器,首先它通過DefaultDocumentLoader將xml信息轉換成dom文檔對象,然後將實際註冊xml文檔定義的bean的任務委託給了
DefaultBeanDefinitionDocumentReader類。改類會將每一個bean 定義註冊到給定的的bean factory。
具體的解析bean的任務則委託給了BeanDefinitionParserDelegate類。
下面看下DefaultBeanDefinitionDocumentReader類的registerBeanDefinitions()方法:
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
logger.debug("Loading bean definitions");
Element root = doc.getDocumentElement();
BeanDefinitionParserDelegate delegate = createHelper(readerContext, root);
preProcessXml(root);
parseBeanDefinitions(root, delegate);
postProcessXml(root);
}
首先對root元素進行預處理,然後在解析改元素,最後對root元素進行後處理。
其實preProcessXml(root)和postProcessXml(root)方法是在完成處理bean定義前後去擴展
處理任何自定義元素,默認沒有實現任何功能。
parseBeanDefinitions()方法則是從根級別解析元素,如果是默認空間http://www.springframework.org/schema/beans或者爲null,則解析默認元素,否則解析自定義元素。
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
if (delegate.isDefaultNamespace(root.getNamespaceURI())) {
NodeList nl = root.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
String namespaceUri = ele.getNamespaceURI();
if (delegate.isDefaultNamespace(namespaceUri)) {
parseDefaultElement(ele, delegate);//解析默認元素
}
else {
delegate.parseCustomElement(ele);//解析自定義元素
}
}
}
}
else {
delegate.parseCustomElement(root); //解析自定義元素
}
}
首先查看 default的解析,default包含如下幾個標籤,分別解析
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
if (DomUtils.nodeNameEquals(ele, IMPORT_ELEMENT)) {
importBeanDefinitionResource(ele);
}
else if (DomUtils.nodeNameEquals(ele, ALIAS_ELEMENT)) {
processAliasRegistration(ele);
}
else if (DomUtils.nodeNameEquals(ele, BEAN_ELEMENT)) { //TODO:處理xml中定義的bean元素
processBeanDefinition(ele, delegate);
}
}
默認元素中bean 定義的解析順序
parseMetaElements(ele, bd);
parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
parseConstructorArgElements(ele, bd);
parsePropertyElements(ele, bd);
在解析子元素和屬性的時候判斷他們的類型(List,Map,Properties,Ref),
根據具體的類型調用相應的方法。解析完成,組裝成BeanComponentDefinition