public void parsePropertyElements(Element beanEle, BeanDefinition bd) { NodeList nl = beanEle.getChildNodes(); // 遍历所有子节点标签 for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); // 判断是否为property标签 if (isCandidateElement(node) && nodeNameEquals(node, PROPERTY_ELEMENT)) { // 开始解析property标签 parsePropertyElement((Element) node, bd); } } }
// 解析标签中的属性 public void parsePropertyElement(Element ele, BeanDefinition bd) { // 获取名字 String propertyName = ele.getAttribute(NAME_ATTRIBUTE); if (!StringUtils.hasLength(propertyName)) { error("Tag 'property' must have a 'name' attribute", ele); return; } this.parseState.push(newPropertyEntry(propertyName)); try { // 如果一个bean中,配置两个property标签,他们名字相同,则不加载 // 即:如果一个bean中配置两个名字相同的property标签,则只有第一个生效。 if (bd.getPropertyValues().contains(propertyName)) { error("Multiple 'property' definitions for property '" + propertyName + "'", ele); return; } // 解析property标签中其他属性,如:ref、value等... Object val = parsePropertyValue(ele, bd, propertyName); // 将name和各个属性值封装成PropertyValue对象 PropertyValue pv = newPropertyValue(propertyName, val); parseMetaElements(ele, pv); pv.setSource(extractSource(ele)); // 将其保存到BeanDefinition中 bd.getPropertyValues().addPropertyValue(pv); } finally { this.parseState.pop(); } }
public Object parsePropertyValue(Element ele, BeanDefinition bd, @Nullable String propertyName) { String elementName = (propertyName != null) ? "<property> element for property '" + propertyName + "'" : "<constructor-arg> element";
// 获取当前property有子标签,只能是ref, value, list, etc中的一种 NodeList nl = ele.getChildNodes(); Element subElement = null; for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); if (node instanceof Element && !nodeNameEquals(node, DESCRIPTION_ELEMENT) && !nodeNameEquals(node, META_ELEMENT)) { // Child element is what we're looking for. if (subElement != null) { error(elementName + " must not contain more than one sub-element", ele); } else { // 当前property包含的子元素 subElement = (Element) node; } } }
// 判断属性值是ref还是value,不允许既是ref又是value boolean hasRefAttribute = ele.hasAttribute(REF_ATTRIBUTE); boolean hasValueAttribute = ele.hasAttribute(VALUE_ATTRIBUTE); if ((hasRefAttribute && hasValueAttribute) || ((hasRefAttribute|| hasValueAttribute) && subElement != null)) { error(elementName + " is only allowed to contain either 'ref' attribute OR 'value' attribute OR sub-element", ele); } if (hasRefAttribute) { // 如果是ref,创建一个对象RuntimeBeanReference,封装ref StringrefName = ele.getAttribute(REF_ATTRIBUTE); if (!StringUtils.hasText(refName)) { error(elementName + " contains empty 'ref' attribute", ele); } RuntimeBeanReferenceref = newRuntimeBeanReference(refName); // 设置这个ref数据对象被当前对象所引用 ref.setSource(extractSource(ele)); return ref; } elseif (hasValueAttribute) { // 如果是value,创建一个TypedStringValue对象,封装value TypedStringValue valueHolder = newTypedStringValue(ele.getAttribute(VALUE_ATTRIBUTE)); // 设置这个value的数据对象,被当前对象所引用 valueHolder.setSource(extractSource(ele)); return valueHolder; } elseif (subElement != null) { // 如果存在子标签,则继续解析子标签 return parsePropertySubElement(subElement, bd); } else { //Neither child element nor "ref" or "value" attribute found. error(elementName + " must specify a refor value", ele); return null; } }