这里的getBeanClass,在ConstantBeanDefinitionParser被重写了,返回了一个工厂类class:
private static class ConstantBeanDefinitionParser extends AbstractSimpleBeanDefinitionParser { @Override protected Class getBeanClass(Element element) { return FieldRetrievingFactoryBean.class; } ... }而doParse,也在ConstantBeanDefinitionParser的父类中AbstractSimpleBeanDefinitionParser进行了重写:
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { NamedNodeMap attributes = element.getAttributes(); // 这里,获取element下的属性 for (int x = 0; x < attributes.getLength(); x++) { Attr attribute = (Attr) attributes.item(x); if (isEligibleAttribute(attribute, parserContext)) { String propertyName = extractPropertyName(attribute.getLocalName()); // 通过attribute.getValue()获取属性值,propertyName为属性名,加入到BeanDefinition builder.addPropertyValue(propertyName, attribute.getValue()); } } postProcess(builder, element); }回头看看我们的xml:
<util:constant static-field= "java.sql.Connection.TRANSACTION_SERIALIZABLE"/>再看看我们debug时,此时的beanDefinition:
这里,获取了beanDefinition后,就是进入到本小节开始的地方,去进行beanDefinition的注册了。
总的来说,的解析,得到了一个BeanDefinition,其class类型为:
public class FieldRetrievingFactoryBean implements FactoryBean<Object>, BeanNameAware, BeanClassLoaderAware, InitializingBean这就是一个工厂bean。工厂bean在后续怎么被使用的,留待下一篇。
总结本篇源码在:
https://gitee.com/ckl111/spring-boot-first-version-learn/tree/master/all-demo-in-spring-learning/spring-xml-demo/src/main/java/org/springframework/utilnamespace中的TestConstant.java
xml的解析demo在:
https://gitee.com/ckl111/spring-boot-first-version-learn/tree/master/all-demo-in-spring-learning/spring-xml-demo/src/test/java/org/springframework/bootstrap/sample
我发现,一个东西,自己看懂可能还行,相对容易点,但是要把这个东西写出来,却是一个大工程。。。看似简单的元素解析,你要把它讲清楚,还真的要点篇幅,哈哈,所以,这也是为什么本篇比较长的原因。
总的来说,再次回答标题,spring到底得到了什么,得到了beanDefinition,本篇里,只得到了一个beanDefinition,还是工厂类型的;后面,我们会看到其他多种多样的元素解析方式。
ok,就到这里,如果大家觉得有帮助,记得点赞。