解析构造注入的参数
//解析构造函数的参数
parseConstructorArgElements(ele, bd);
进入其中源码:
public void parseConstructorArgElements(Element beanEle, BeanDefinition bd)
{
//获取到所有的子元素
NodeList nl = beanEle.getChildNodes();
//遍历取出所有子元素
for (int i = 0; i < nl.getLength(); i++)
{
Node node = nl.item(i);
//判断元素是否叫CONSTRUCTOR_ARG_ELEMENT
if (isCandidateElement(node) && nodeNameEquals(node, CONSTRUCTOR_ARG_ELEMENT))
{
//解析构造器
parseConstructorArgElement((Element) node, bd);
}
}
}
解析属性注入的参数
//解析properties子元素
parsePropertyElements(ele, bd);
可以看里面的源码和构造注入基本相同:
/**
* Parse property sub-elements of the given bean element.
*/
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))
{
parsePropertyElement((Element) node, bd);
}
}
}
所以我们能看出来他的核心就在parsePropertyElement
,我们要着重看下里面的源代码!
public void parsePropertyElement(Element ele, BeanDefinition bd)
{
//获取name属性
String propertyName = ele.getAttribute(NAME_ATTRIBUTE);
//没有name属性的话就报错
if (!StringUtils.hasLength(propertyName))
{
error("Tag 'property' must have a 'name' attribute", ele);
return;
}
this.parseState.push(new PropertyEntry(propertyName));
try
{
if (bd.getPropertyValues().contains(propertyName))
{
error("Multiple 'property' definitions for property '" + propertyName + "'", ele);
return;
}
//获取属性值,需要点进去分析!
Object val = parsePropertyValue(ele, bd, propertyName);
PropertyValue pv = new PropertyValue(propertyName, val);
parseMetaElements(ele, pv);
pv.setSource(extractSource(ele));
bd.getPropertyValues().addPropertyValue(pv);
} finally
{
this.parseState.pop();
}
}
首先是获取name属性,没有就报错。获取到之后,里面调用parsePropertyValue
方法来进行解析:
//ref是引用另外一个定义好的bean
boolean hasRefAttribute = ele.hasAttribute(REF_ATTRIBUTE);
boolean hasValueAttribute = ele.hasAttribute(VALUE_ATTRIBUTE);
//ref和value属性不能共存,不然报错!
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)
{
String refName = ele.getAttribute(REF_ATTRIBUTE);
if (!StringUtils.hasText(refName))
{
error(elementName + " contains empty 'ref' attribute", ele);
}
RuntimeBeanReference ref = new RuntimeBeanReference(refName);
ref.setSource(extractSource(ele));
return ref;
} else if (hasValueAttribute)
{
TypedStringValue valueHolder = new TypedStringValue(ele.getAttribute(VALUE_ATTRIBUTE));
valueHolder.setSource(extractSource(ele));
return valueHolder;
} else if (subElement != null)
{
return parsePropertySubElement(subElement, bd);
} else
{
// Neither child element nor "ref" or "value" attribute found.
error(elementName + " must specify a ref or value", ele);
return null;
}
我拿了一段核心出来!
首先判断bean元素中有ref属性,他通过RuntimeBeanReference
,对需要的属性进行填充!
判断是否有value元素TypedStringValue
:
public TypedStringValue(@Nullable String value) {
setValue(value);
}
解析qualifier子元素
进入parseQualifierElement
查看源码,其实大致一致!
解析bean name的定义
if (containingBean != null)
{
beanName = BeanDefinitionReaderUtils.generateBeanName(
beanDefinition, this.readerContext.getRegistry(), true);
}
源码:
public static String generateBeanName(
BeanDefinition definition, BeanDefinitionRegistry registry, boolean isInnerBean)
throws BeanDefinitionStoreException {
//获取bean的class名字
String generatedBeanName = definition.getBeanClassName();
if (generatedBeanName == null) {//如果bean的名字为空且父元素不为空
if (definition.getParentName() != null) {
//那就在父名称后面加个$child
generatedBeanName = definition.getParentName() + "$child";
}
else if (definition.getFactoryBeanName() != null) {//如果bean的名字为空且工厂名称不为空
//那就在工厂名字后面加个$created
generatedBeanName = definition.getFactoryBeanName() + "$created";
}
}
if (!StringUtils.hasText(generatedBeanName)) {
throw new BeanDefinitionStoreException("Unnamed bean definition specifies neither " +
"'class' nor 'parent' nor 'factory-bean' - can't generate bean name");
}
if (isInnerBean) {
// Inner bean: generate identity hashcode suffix.
return generatedBeanName + GENERATED_BEAN_NAME_SEPARATOR + ObjectUtils.getIdentityHexString(definition);
}
// Top-level bean: use plain class name with unique suffix if necessary.
//顶级bean:必要时使用带有唯一后缀的普通类名。
return uniqueBeanName(generatedBeanName, registry);
}
上面这一系列完成之后,也就是完成了bean属性的定义!
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
public BeanDefinitionHolder decorateBeanDefinitionIfRequired(
Element ele, BeanDefinitionHolder originalDef, @Nullable BeanDefinition containingBd)
{
BeanDefinitionHolder finalDefinition = originalDef;
// Decorate based on custom attributes first.
NamedNodeMap attributes = ele.getAttributes();
//一个是用于对所有的属性进行遍历处理
for (int i = 0; i < attributes.getLength(); i++)
{
Node node = attributes.item(i);
finalDefinition = decorateIfRequired(node, finalDefinition, containingBd);
}
// Decorate based on custom nested elements.
NodeList children = ele.getChildNodes();
//另一个是对所有的子节点进行处理
for (int i = 0; i < children.getLength(); i++)
{
Node node = children.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE)
{
finalDefinition = decorateIfRequired(node, finalDefinition, containingBd);
}
}
return finalDefinition;
}
注册最终装饰的实例到工厂
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
后面会对立面的源码进行深度剖析!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/16382.html