曹工说Spring Boot源码(9)-- Spring解析xml文件,到底从中得到了什么(context命名空间上) (2)

我们切入到org.springframework.context.config.ContextNamespaceHandler,查找下该元素的解析器。

public class ContextNamespaceHandler extends NamespaceHandlerSupport { public void init() { registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser()); registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser()); registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser()); registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser()); registerBeanDefinitionParser("load-time-weaver", new LoadTimeWeaverBeanDefinitionParser()); registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser()); registerBeanDefinitionParser("mbean-export", new MBeanExportBeanDefinitionParser()); registerBeanDefinitionParser("mbean-server", new MBeanServerBeanDefinitionParser()); } }

我们可以看到,本元素的解析器是:PropertyPlaceholderBeanDefinitionParser。

先看看类继承结构:

曹工说Spring Boot源码(9)-- Spring解析xml文件,到底从中得到了什么(context命名空间上)

大家注意第三层,类名里,有Single字样,说明了它是单身狗?不是。说明这个xml元素解析器,最终只得到一个bean definition。

第四层的AbstractPropertyLoadingBeanDefinitionParser,就是提供一个抽象类,提取一些和对应的解析器中公共的方法。

可以简单一看:

abstract class AbstractPropertyLoadingBeanDefinitionParser extends AbstractSingleBeanDefinitionParser { @Override protected boolean shouldGenerateId() { return true; } // 获取一些属性 @Override protected void doParse(Element element, BeanDefinitionBuilder builder) { String location = element.getAttribute("location"); if (StringUtils.hasLength(location)) { String[] locations = StringUtils.commaDelimitedListToStringArray(location); builder.addPropertyValue("locations", locations); } String propertiesRef = element.getAttribute("properties-ref"); if (StringUtils.hasLength(propertiesRef)) { builder.addPropertyReference("properties", propertiesRef); } String fileEncoding = element.getAttribute("file-encoding"); if (StringUtils.hasLength(fileEncoding)) { builder.addPropertyValue("fileEncoding", fileEncoding); } String order = element.getAttribute("order"); if (StringUtils.hasLength(order)) { builder.addPropertyValue("order", Integer.valueOf(order)); } builder.addPropertyValue("ignoreResourceNotFound", Boolean.valueOf(element.getAttribute("ignore-resource-not-found"))); builder.addPropertyValue("localOverride", Boolean.valueOf(element.getAttribute("local-override"))); builder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); } }

看了父,不看正主也说不过去,这里呢,正主是真的简单:

class PropertyPlaceholderBeanDefinitionParser extends AbstractPropertyLoadingBeanDefinitionParser { private static final String SYSTEM_PROPERTIES_MODE_ATTRIB = "system-properties-mode"; private static final String SYSTEM_PROPERTIES_MODE_DEFAULT = "ENVIRONMENT"; // 这里获取bean的class,注意,这里的class,是不是和前面:等价用法那一节里,配置的bean的class一样 // 所以啊,context:property-placeholder和等价用法里的底层实现,还是一样的 @Override protected Class<?> getBeanClass(Element element) { ... return PropertyPlaceholderConfigurer.class; } @Override protected void doParse(Element element, BeanDefinitionBuilder builder) { super.doParse(element, builder); builder.addPropertyValue("ignoreUnresolvablePlaceholders", Boolean.valueOf(element.getAttribute("ignore-unresolvable"))); String systemPropertiesModeName = element.getAttribute(SYSTEM_PROPERTIES_MODE_ATTRIB); if (StringUtils.hasLength(systemPropertiesModeName) && !systemPropertiesModeName.equals(SYSTEM_PROPERTIES_MODE_DEFAULT)) { builder.addPropertyValue("systemPropertiesModeName", "SYSTEM_PROPERTIES_MODE_"+systemPropertiesModeName); } } }

大家可以看注释,这里返回的class,和等价用法里的的class是一模一样。说明了什么呢?大家这么聪明,不用我多说了。

这个class,PropertyPlaceholderConfigurer,其实还是比较特别的,我们看看其类图:

曹工说Spring Boot源码(9)-- Spring解析xml文件,到底从中得到了什么(context命名空间上)

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpdssz.html