解析XML的入口類java
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); } }
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); } }
能夠理解爲遞歸調用,進行解析spring
<beans> <import resource="file://e:/a.xml"></import> </beans>
<bean> <alias name="a" alias="a1"></alias> </bean>
遞歸解析ui
<beans> <beans profile="dev"></beans> </beans>
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
獲取與設置某個對象上的屬性
AttributeAccessorSupport
AttributeAccessor的抽象實現
BeanMetadataAttributeAccessor
AttributeAccessorSupport的實現
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
對象
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的擴充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); }
say方法是抽象的,必須是無參的而且返回值必須是b對象的類型。
<bean> <lookup-method name="say" bean="b"> </lookup-method> </bean>
say方法的名稱,參數類型與順序,參數個數,返回值類型必須與b對象的一致
<bean> <replaced-method name="say" replacer="b"> <arg-type match="java.lang.String"></arg-type> </replaced-method> </bean>
構造參數注入 若是存在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 name="a" ref=""></property> <property name="a" value=""></property> <property name="a"> //子標籤 </property> </bean>
<bean> <qualifier type="xxx" value=""></qualifier> </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
子標籤解析類