前言
分析内容property-placeholder、property-override节点
// 属性配置
<context:property-placeholder location="classpath:context.properties">
类的结构关系
* AbstractBeanDefinitionParser
* AbstractSingleBeanDefinitionParser
* AbstractPropertyLoadingBeanDefinitionParser
* PropertyPlaceholderBeanDefinitionParser
源码分析
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#parseBeanDefinitions
/**
* Parse the elements at the root level in the document:
* "import", "alias", "bean".
* @param root the DOM root element of the document
*/
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
//Bean 定义的 Document 对象使用了 Spring 默认的 XML 命名空间
if (delegate.isDefaultNamespace(root)) {
NodeList nl = root.getChildNodes();
// //获得 Document 节点是 XML 元素
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
//Bean 定义的 Document 的元素节点使用的是 Spring 默认的 XML 命名空间
if (delegate.isDefaultNamespace(ele)) {
//使用 Spring 的 Bean 规则解析元素节点
parseDefaultElement(ele, delegate);
}
else {
没有使用 Spring 默认的 XML 命名空间,则使用用户自定义的解//析规则解析元素
delegate.parseCustomElement(ele);
}
}
}
}
else {
//Document 的根节点没有使用 Spring 默认的命名空间,则使用用户自定义的
//解析规则解析 Document 根节点
delegate.parseCustomElement(root);
}
}
org.springframework.beans.factory.xml.BeanDefinitionParserDelegate#parseCustomElement(org.w3c.dom.Element)
public BeanDefinition parseCustomElement(Element ele) {
return parseCustomElement(ele, null);
}
org.springframework.beans.factory.xml.BeanDefinitionParserDelegate#parseCustomElement(org.w3c.dom.Element, org.springframework.beans.factory.config.BeanDefinition)
public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) {
// 第一步: 获取用户自定义的命名空间
String namespaceUri = getNamespaceURI(ele);
if (namespaceUri == null) {
return null;
}
// 第二步: 获取命名空间解析器
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
if (handler == null) {
error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
return null;
}
// 第三步: 解析
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}
获取命名空间解析器
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
org.springframework.beans.factory.xml.NamespaceHandler#init
// 初始化namespaceHandler类 UtilNamespaceHandler
namespaceHandler.init();
org.springframework.context.config.ContextNamespaceHandler#init
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());
}
org.springframework.beans.factory.xml.NamespaceHandler#parse
// 第三步: 解析
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
org.springframework.beans.factory.xml.BeanDefinitionParser#parse
public BeanDefinition parse(Element element, ParserContext parserContext) {
// 第一步: 根据元素的类型查询对应的解析器
BeanDefinitionParser parser = findParserForElement(element, parserContext);
// 第二步: 解析....
return (parser != null ? parser.parse(element, parserContext) : null);
}
org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser#doParse(org.w3c.dom.Element, org.springframework.beans.factory.xml.ParserContext, org.springframework.beans.factory.support.BeanDefinitionBuilder)
// 第六步: 解析.......
doParse(element, parserContext, builder);
org.springframework.context.config.PropertyPlaceholderBeanDefinitionParser#doParse
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
super.doParse(element, parserContext, builder);
// 获取ignore-unresolvable属性,默认为false,true代表解析不了属性不抛异常
builder.addPropertyValue("ignoreUnresolvablePlaceholders",
Boolean.valueOf(element.getAttribute("ignore-unresolvable")));
//获取system-properties-mode属性
String systemPropertiesModeName = element.getAttribute(SYSTEM_PROPERTIES_MODE_ATTRIBUTE);
if (StringUtils.hasLength(systemPropertiesModeName) &&
!systemPropertiesModeName.equals(SYSTEM_PROPERTIES_MODE_DEFAULT)) {
builder.addPropertyValue("systemPropertiesModeName", "SYSTEM_PROPERTIES_MODE_" + systemPropertiesModeName);
}
if (element.hasAttribute("value-separator")) {
builder.addPropertyValue("valueSeparator", element.getAttribute("value-separator"));
}
if (element.hasAttribute("trim-values")) {
builder.addPropertyValue("trimValues", element.getAttribute("trim-values"));
}
if (element.hasAttribute("null-value")) {
builder.addPropertyValue("nullValue", element.getAttribute("null-value"));
}
}
org.springframework.context.config.AbstractPropertyLoadingBeanDefinitionParser#doParse
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
// 获取location属性,支持,分隔,表明指定读取配置文件的路径
String location = element.getAttribute("location");
if (StringUtils.hasLength(location)) {
location = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(location);
String[] locations = StringUtils.commaDelimitedListToStringArray(location);
builder.addPropertyValue("locations", locations);
}
// 获取properties-ref属性,设置properties文件的引用名
String propertiesRef = element.getAttribute("properties-ref");
if (StringUtils.hasLength(propertiesRef)) {
builder.addPropertyReference("properties", propertiesRef);
}
//获取file-encoding属性,文件解析字符编码集
String fileEncoding = element.getAttribute("file-encoding");
if (StringUtils.hasLength(fileEncoding)) {
builder.addPropertyValue("fileEncoding", fileEncoding);
}
// 获取order属性,用于排序
String order = element.getAttribute("order");
if (StringUtils.hasLength(order)) {
builder.addPropertyValue("order", Integer.valueOf(order));
}
// 获取ignore-resource-not-found属性,默认为false,表明找不到资源是否往外抛异常
builder.addPropertyValue("ignoreResourceNotFound",
Boolean.valueOf(element.getAttribute("ignore-resource-not-found")));
//获取local-override属性,默认为false,true表明先使用文件中的属性,找不到再使用环境变量中的属性
builder.addPropertyValue("localOverride",
Boolean.valueOf(element.getAttribute("local-override")));
builder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
}