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

spring application 之 Xml解析-LMLPHP
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

子标签解析类

06-09 22:49