热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Spring源码讲解之parseBeanDefinitionElement

parseBeanDefinitionElement方法是在org.springframework.beans.factory.xml.BeanDefinitionParserDe

parseBeanDefinitionElement 方法是在 org.springframework.beans.factory.xml.BeanDefinitionParserDelegate 类中定义的,主要作用是解析 bean 元素并将其结果赋值给 org.springframework.beans.factory.config.BeanDefinitionHolder 实例进行存储。 该方法接收一个类型为 org.w3c.dom.Element 的参数,返回值类为 org.springframework.beans.factory.config.BeanDefinitionHolder。该方法会在org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.processBeanDefinition(Element, BeanDefinitionParserDelegate) 方法中调用。


源码

@Nullable
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {return parseBeanDefinitionElement(ele, null);
}

parseBeanDefinitionElement 方法的实现

@Nullable
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, &#64;Nullable BeanDefinition containingBean) {// 获取 id 属性String id &#61; ele.getAttribute(ID_ATTRIBUTE);// 获取 name 属性String nameAttr &#61; ele.getAttribute(NAME_ATTRIBUTE);List<String> aliases &#61; new ArrayList<>();if (StringUtils.hasLength(nameAttr)) {// 解析 name 属性中的值String[] nameArr &#61; StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);aliases.addAll(Arrays.asList(nameArr));}String beanName &#61; id;if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {beanName &#61; aliases.remove(0);if (logger.isTraceEnabled()) {logger.trace("No XML &#39;id&#39; specified - using &#39;" &#43; beanName &#43;"&#39; as bean name and " &#43; aliases &#43; " as aliases");}}if (containingBean &#61;&#61; null) {// 检查 bean 名称和 bean 别名是否唯一checkNameUniqueness(beanName, aliases, ele);}// 重点方法// 解析 bean 元素到 BeanDefinition 中AbstractBeanDefinition beanDefinition &#61; parseBeanDefinitionElement(ele, beanName, containingBean);if (beanDefinition !&#61; null) {// 如果 beanName 为空&#xff0c;通过 beanDefinition 信息生成一个 beanNameif (!StringUtils.hasText(beanName)) {try {if (containingBean !&#61; null) {beanName &#61; BeanDefinitionReaderUtils.generateBeanName(beanDefinition, this.readerContext.getRegistry(), true);}else {beanName &#61; this.readerContext.generateBeanName(beanDefinition);// Register an alias for the plain bean class name, if still possible,// if the generator returned the class name plus a suffix.// This is expected for Spring 1.2/2.0 backwards compatibility.String beanClassName &#61; beanDefinition.getBeanClassName();if (beanClassName !&#61; null &&beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {aliases.add(beanClassName);}}if (logger.isTraceEnabled()) {logger.trace("Neither XML &#39;id&#39; nor &#39;name&#39; specified - " &#43;"using generated bean name [" &#43; beanName &#43; "]");}}catch (Exception ex) {error(ex.getMessage(), ele);return null;}}String[] aliasesArray &#61; StringUtils.toStringArray(aliases);return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);}return null;
}

parseBeanDefinitionElement 方法的实现

&#64;Nullable
public AbstractBeanDefinition parseBeanDefinitionElement(Element ele, String beanName, &#64;Nullable BeanDefinition containingBean) {// 记录 bean 的解析状态this.parseState.push(new BeanEntry(beanName));String className &#61; null;if (ele.hasAttribute(CLASS_ATTRIBUTE)) {// 获取 calss 属性的值className &#61; ele.getAttribute(CLASS_ATTRIBUTE).trim();}String parent &#61; null;if (ele.hasAttribute(PARENT_ATTRIBUTE)) {// 获取 parent 属性的值parent &#61; ele.getAttribute(PARENT_ATTRIBUTE);}try {// 创建一个 AbstractBeanDefinition 实例// 默认类型是 org.springframework.beans.factory.support.GenericBeanDefinitionAbstractBeanDefinition bd &#61; createBeanDefinition(className, parent);// 解析 bean 定义相关的属性parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));// 解析 meta 子元素parseMetaElements(ele, bd);// 解析 lookup-method 子元素parseLookupOverrideSubElements(ele, bd.getMethodOverrides());// 解析 replaced-method 子元素parseReplacedMethodSubElements(ele, bd.getMethodOverrides());// 解析 constructor-arg 子元素parseConstructorArgElements(ele, bd);// 解析 property 子元素parsePropertyElements(ele, bd);// 解析 qualifier 子元素parseQualifierElements(ele, bd);bd.setResource(this.readerContext.getResource());bd.setSource(extractSource(ele));return bd;}catch (ClassNotFoundException ex) {error("Bean class [" &#43; className &#43; "] not found", ele, ex);}catch (NoClassDefFoundError err) {error("Class that bean class [" &#43; className &#43; "] depends on not found", ele, err);}catch (Throwable ex) {error("Unexpected failure during bean definition parsing", ele, ex);}finally {this.parseState.pop();}return null;
}

parseBeanDefinitionElement 方法讲解完毕&#xff0c;部分方法没有进行详细讲解&#xff08;例如&#xff1a;parseBeanDefinitionAttributes、parseMetaElements 等方法&#xff09;&#xff0c;此部分代码都在 org.springframework.beans.factory.xml.BeanDefinitionParserDelegate 类中进行定义和实现&#xff0c;想了解的朋友可以去此类中进行查看。


推荐阅读
author-avatar
金爽20111018
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有