Spring根据配置文件解析占位符

背景

在Spring中,使用${user.name}的形式,能够自动从配置文件中读取user.name的值进行替换。包括AutowiredAnnotationBeanPostProcessor提供的@Value的注入功能。

原理

PropertyResolver

该接口的作用是解析属性值,提供了一系列获取属性以及解析属性的方法。
在这里插入图片描述
其中resolvePlaceholders(String text)resolveRequiredPlaceholders(String text)提供了解析占位符${}属性解析的功能。

在这里插入图片描述
从继承图可以看出,我们熟知的StandardEnvironment也是一个PropertyResolver,在其父类AbstractEnvironment的方法:


private final MutablePropertySources propertySources = new MutablePropertySources(this.logger);

private final ConfigurablePropertyResolver propertyResolver =
			new PropertySourcesPropertyResolver(this.propertySources);
			
@Override
	public String resolvePlaceholders(String text) {
		return this.propertyResolver.resolvePlaceholders(text);
	}

可以看出解析的动作交给了propertyResolver来进行,它是一个ConfigurablePropertyResolver,从继承图同样可以看出是一个PropertyResolver,且其内部持有了一个PropertySourcesAbstractEnvironment默认提供了一个Log并使用组合对象MutablePropertySources来持有多个PropertySources,在构造函数中可以调用子类复写的customizePropertySources来添加额外的PropertySources

@Override
	protected void customizePropertySources(MutablePropertySources propertySources) {
		propertySources.addLast(new MapPropertySource(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, getSystemProperties()));
		propertySources.addLast(new SystemEnvironmentPropertySource(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, getSystemEnvironment()));
	}

PropertySources

持有key/value属性值对,提供根据name获取value的功能

解析流程

PropertyResolver解析占位符时,会创建一个占位符辅助器PropertyPlaceholderHelper

@Override
	public String resolveRequiredPlaceholders(String text) throws IllegalArgumentException {
		if (this.strictHelper == null) {
			this.strictHelper = createPlaceholderHelper(false);
		}
		return doResolvePlaceholders(text, this.strictHelper);
	}
private PropertyPlaceholderHelper createPlaceholderHelper(boolean ignoreUnresolvablePlaceholders) {
		return new PropertyPlaceholderHelper(this.placeholderPrefix, this.placeholderSuffix,
				this.valueSeparator, ignoreUnresolvablePlaceholders);
	}

PropertyPlaceholderHelper持有占位符的前缀${,后缀},值分隔符:信息,用于将${user.name:123}解析出属性名user.name以及默认值123,然后从PropertySources中获取user.name对应的属性值,如果没有就使用默认值。

总结

PropertySources是资源信息,也是我们的配置属性
PropertyResolver是解析器,用于执行解析的动作。
PropertyPlaceholderHelper是占位符解析器,用于确认占位符字段,方便提取具体的属性名和默认值


版权声明:本文为Mutou_ren原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。