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
获取与设置某个对象上的属性
AttributeAccessorSupport
AttributeAccessor的抽象实现
BeanMetadataAttributeAccessor
AttributeAccessorSupport的实现
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({});相关文章推荐
- Android 创建与解析XML(四)—— Pull方式
- 解析XML
- javascript解析返回的xml各式的字符串
- XML——XML解析之DOM
- XML文件解析
- XML解析
- php中xml语法解析总结
- 理解Tomcat(一) 利用Digester解析xml文件
- Menu:Xml属性全解析
- testNG之XML文件内容解析--suite,class,test,package
- XML解析
- oracle存储过程通过http接收xml文件并解析入库
- XML 解析中,如何排除控制字符
- 使用 dom4j 解析 XML
- Android Manifest.xml解析
- xml学习笔记(3)xml解析方式
- 进入黑马day2-解析xml三种方法(2)sax解析器解析
- 浅谈XML 解析技术(三) JDOM解析
- jquery解析xml字符串简单示例
- VC解析XML--使用CMarkup类解析XML