您的位置:首页 > 编程语言 > Java开发

spring application 之 Xml解析

2019-06-10 07:18 2111 查看

org.springframework.beans.factory.xml.XmlBeanDefinitionReader

解析XML的入口类

DefaultBeanDefinitionDocumentReader

XML标签解析类

protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
if (delegate.isDefaultNamespace(root)) {
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;
if (delegate.isDefaultNamespace(ele)) {
parseDefaultElement(ele, delegate);
}
else {
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}

解析默认的beans标签

private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
importBeanDefinitionResource(ele);
}
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
processAliasRegistration(ele);
}
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
processBeanDefinition(ele, delegate);
}
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// recurse
doRegisterBeanDefinitions(ele);
}
}

解析beans下的import标签

可以理解为递归调用,进行解析

<beans>
<import resource="file://e:/a.xml"></import>
</beans>

解析beans下的alias标签

<bean>
<alias name="a" alias="a1"></alias>
</bean>

解析beans下的beans标签

递归解析

<beans>
<beans profile="dev"></beans>
</beans>

解析beans下的bean标签

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// Register the final decorated instance.
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// Send registration event.
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
<bean id="" name=""></bean>

优先用id,name作为别名
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
解析class,parent

<bean class="spring.A" parent="b"></bean>

创建abstractBeanDefinition

`AbstractBeanDefinition bd = createBeanDefinition(className, parent);`
public static AbstractBeanDefinition createBeanDefinition(
@Nullable String parentName, @Nullable String className, @Nullable ClassLoader classLoader) throws ClassNotFoundException {

GenericBeanDefinition bd = new GenericBeanDefinition();
bd.setParentName(parentName);
if (className != null) {
if (classLoader != null) {
bd.setBeanClass(ClassUtils.forName(className, classLoader));
}
else {
bd.setBeanClassName(className);
}
}
return bd;
}


BeanMetadataElement 描述某个对象上的元素据
AttributeAccessor获取与设置某个对象上的属性
AttributeAccessorSupportAttributeAccessor的抽象实现
BeanMetadataAttributeAccessorAttributeAccessorSupport的实现
BeanDefinition对像描述,主要有以下几个信息

void setParentName(@Nullable String parentName);
void setBeanClassName(@Nullable String beanClassName);
void setScope(@Nullable String scope);
void setLazyInit(boolean lazyInit);
void setDependsOn(@Nullable String... dependsOn);
void setAutowireCandidate(boolean autowireCandidate);
void setPrimary(boolean primary);
void setFactoryBeanName(@Nullable String factoryBeanName);
void setFactoryMethodName(@Nullable String factoryMethodName);
ConstructorArgumentValues getConstructorArgumentValues();
MutablePropertyValues getPropertyValues();

先通过className,parentName创建一个 GenericBeanDefinition

解析bean标签上的属性

parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
<bean scope="single" abstract="false" lazy-init="false"
autowire="default" depends-on="" primary="true" init-method="init"
destroy-method="close" factory-bean="" factory-method=""
>
</bean>

解析bean下面的meta标签

对Bean的扩充

parseMetaElements(ele, bd);

比如:ConfigurationClassPostProcessor 的先后顺序就有用到

public static int getOrder(BeanDefinition beanDef) {
Integer order = (Integer) beanDef.getAttribute(ORDER_ATTRIBUTE);
return (order != null ? order : Ordered.LOWEST_PRECEDENCE);
}

解析bean下的lookup-method标签

say方法是抽象的,必须是无参的并且返回值必须是b对象的类型。

<bean>
<lookup-method name="say" bean="b">
</lookup-method>
</bean>

解析bean下的replaced-method标签

say方法的名称,参数类型与顺序,参数个数,返回值类型必须与b对象的一致

<bean>
<replaced-method name="say" replacer="b">
<arg-type match="java.lang.String"></arg-type>
</replaced-method>
</bean>

解析bean下的constructor-agr标签

构造参数注入 如果存在index属性,以下条件都符合要求,如果没有index,type或者name可能都需要

<bean>
<constructor-arg index="1" ref="b"/>
<constructor-arg index="2" value="b"/>
<constructor-arg index="3">
<bean></bean>
</constructor-arg>
<constructor-arg index="4">
<ref bean="b"></ref>
</constructor-arg>
<constructor-arg index="5">
<ref parent="b"></ref> //从父容器中获取
</constructor-arg>
<constructor-arg index="6">
<idref bean="b"></idref> //返回bean的名称,而不是bean的对象
</constructor-arg>
<constructor-arg index="7">
<value>b</value>
</constructor-arg>
<constructor-arg index="8">
<null></null>
</constructor-arg>
<constructor-arg index="9">
<array value-type="java.lang.String">
//递归解析子标签
</array>
</constructor-arg>
<constructor-arg index="10">
<list>
//递归解析子标签
</list>
</constructor-arg>
<constructor-arg index="11">
<set>
//递归解析子标签
</set>
</constructor-arg>
<constructor-arg index="12">
<map>
//这里可以用key,key-ref value value-ref或者子标签
<entry key="b" value="b"></entry>
<entry key-ref="b" value-ref="b"></entry>
<entry>
<key>子标签</key>
<value>子标签</value>
</entry>
</map>
</constructor-arg>
<constructor-arg index="13">
<props>
<prop key="b">b</prop>
</props>
</constructor-arg>
</bean>

解析bean的property标签

<bean>
<property name="a" ref=""></property>
<property name="a" value=""></property>
<property name="a">
//子标签
</property>
</bean>

解析bean的qualifier标签

<bean>
<qualifier type="xxx" value=""></qualifier>
</bean>

对beans下的bean进行装饰

protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// Register the final decorated instance.
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// Send registration event.
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
public BeanDefinitionHolder decorateBeanDefinitionIfRequired(
Element ele, BeanDefinitionHolder definitionHolder, @Nullable BeanDefinition containingBd) {

BeanDefinitionHolder finalDefinition = definitionHolder;

// 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;
}

装饰处理类配置在META-INF/spring.handlers

解析自定义标签

自定义标签处理类配置在META-INF/spring.handlers

BeanDefinitionValueResolver

子标签解析类

(adsbygoogle = window.adsbygoogle || []).push({});
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  DeleGate Spring Java Element