spring application 之 Xml解析

org.springframework.beans.factory.xml.XmlBeanDefinitionReader

解析XML的入口類java

DefaultBeanDefinitionDocumentReader

XML標籤解析類node

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標籤

能夠理解爲遞歸調用,進行解析spring

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

解析beans下的alias標籤

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

解析beans下的beans標籤

遞歸解析ui

<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,parentspa

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

建立abstractBeanDefinitioncode

`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對像描述,主要有如下幾個信息xml

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的擴充blog

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

子標籤解析類

相關文章
相關標籤/搜索