spring bean 默许解析流程
以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