1.PropertyResolver
PropertyResolver这个接口只定义了一些判断Perperties数据进行校验,获取,和解析字符串的基本方法,这里的
String resolvePlaceholders(String text); String resolveRequiredPlaceholders(String text) throws IllegalArgumentException; 是我们最终想要的方法,最终的实现类也主要是使用这两个方法
public interface PropertyResolver {/*** Return whether the given property key is available for resolution,* i.e. if the value for the given key is not {@code null}.*/boolean containsProperty(String key);/*** Return the property value associated with the given key,* or {@code null} if the key cannot be resolved.* @param key the property name to resolve* @see #getProperty(String, String)* @see #getProperty(String, Class)* @see #getRequiredProperty(String)*/@NullableString getProperty(String key);/*** Return the property value associated with the given key, or* {@code defaultValue} if the key cannot be resolved.* @param key the property name to resolve* @param defaultValue the default value to return if no value is found* @see #getRequiredProperty(String)* @see #getProperty(String, Class)*/String getProperty(String key, String defaultValue);/*** Return the property value associated with the given key,* or {@code null} if the key cannot be resolved.* @param key the property name to resolve* @param targetType the expected type of the property value* @see #getRequiredProperty(String, Class)*/@Nullable<T> T getProperty(String key, Class<T> targetType);/*** Return the property value associated with the given key,* or {@code defaultValue} if the key cannot be resolved.* @param key the property name to resolve* @param targetType the expected type of the property value* @param defaultValue the default value to return if no value is found* @see #getRequiredProperty(String, Class)*/<T> T getProperty(String key, Class<T> targetType, T defaultValue);/*** Return the property value associated with the given key (never {@code null}).* @throws IllegalStateException if the key cannot be resolved* @see #getRequiredProperty(String, Class)*/String getRequiredProperty(String key) throws IllegalStateException;/*** Return the property value associated with the given key, converted to the given* targetType (never {@code null}).* @throws IllegalStateException if the given key cannot be resolved*/<T> T getRequiredProperty(String key, Class<T> targetType) throws IllegalStateException;/*** Resolve ${...} placeholders in the given text, replacing them with corresponding* property values as resolved by {@link #getProperty}. Unresolvable placeholders with* no default value are ignored and passed through unchanged.* @param text the String to resolve* @return the resolved String (never {@code null})* @throws IllegalArgumentException if given text is {@code null}* @see #resolveRequiredPlaceholders*/String resolvePlaceholders(String text);/*** Resolve ${...} placeholders in the given text, replacing them with corresponding* property values as resolved by {@link #getProperty}. Unresolvable placeholders with* no default value will cause an IllegalArgumentException to be thrown.* @return the resolved String (never {@code null})* @throws IllegalArgumentException if given text is {@code null}* or if any placeholders are unresolvable*/String resolveRequiredPlaceholders(String text) throws IllegalArgumentException;}
2.ConfigurablePropertyResolver
ConfigurablePropertyResolver 定义了解析表达式的时候需要用到的一些配置方法,比如:识别表达式的时候要用到的 前缀( ${ ),后缀( } ),还有对替换表达式的值 进行类型转换需要用到的ConfigurableConversionService,我们自定义的 ConversionService 可以通过该接口提供的方法进行配置。
/*** Configuration interface to be implemented by most if not all {@link PropertyResolver}* types. Provides facilities for accessing and customizing the* {@link org.springframework.core.convert.ConversionService ConversionService}* used when converting property values from one type to another.** @author Chris Beams* @since 3.1*/
public interface ConfigurablePropertyResolver extends PropertyResolver {/*** Return the {@link ConfigurableConversionService} used when performing type* conversions on properties.* <p>The configurable nature of the returned conversion service allows for* the convenient addition and removal of individual {@code Converter} instances:* <pre class="code">* ConfigurableConversionService cs = env.getConversionService();* cs.addConverter(new FooConverter());* </pre>* @see PropertyResolver#getProperty(String, Class)* @see org.springframework.core.convert.converter.ConverterRegistry#addConverter*/ConfigurableConversionService getConversionService();/*** Set the {@link ConfigurableConversionService} to be used when performing type* conversions on properties.* <p><strong>Note:</strong> as an alternative to fully replacing the* {@code ConversionService}, consider adding or removing individual* {@code Converter} instances by drilling into {@link #getConversionService()}* and calling methods such as {@code #addConverter}.* @see PropertyResolver#getProperty(String, Class)* @see #getConversionService()* @see org.springframework.core.convert.converter.ConverterRegistry#addConverter*/void setConversionService(ConfigurableConversionService conversionService);/*** Set the prefix that placeholders replaced by this resolver must begin with.*/void setPlaceholderPrefix(String placeholderPrefix);/*** Set the suffix that placeholders replaced by this resolver must end with.*/void setPlaceholderSuffix(String placeholderSuffix);/*** Specify the separating character between the placeholders replaced by this* resolver and their associated default value, or {@code null} if no such* special character should be processed as a value separator.*/void setValueSeparator(@Nullable String valueSeparator);/*** Set whether to throw an exception when encountering an unresolvable placeholder* nested within the value of a given property. A {@code false} value indicates strict* resolution, i.e. that an exception will be thrown. A {@code true} value indicates* that unresolvable nested placeholders should be passed through in their unresolved* ${...} form.* <p>Implementations of {@link #getProperty(String)} and its variants must inspect* the value set here to determine correct behavior when property values contain* unresolvable placeholders.* @since 3.2*/void setIgnoreUnresolvableNestedPlaceholders(boolean ignoreUnresolvableNestedPlaceholders);/*** Specify which properties must be present, to be verified by* {@link #validateRequiredProperties()}.*/void setRequiredProperties(String... requiredProperties);/*** Validate that each of the properties specified by* {@link #setRequiredProperties} is present and resolves to a* non-{@code null} value.* @throws MissingRequiredPropertiesException if any of the required* properties are not resolvable.*/void validateRequiredProperties() throws MissingRequiredPropertiesException;}
3.AbstractPropertyResolver
AbstractPropertyResolver对 ConfigurablePropertyResolver和 PropertyResolver 中定义的方法进行实现,主要的方法
@Override
public String resolvePlaceholders(String text) {if (this.nonStrictHelper == null) {this.nonStrictHelper = createPlaceholderHelper(true);}return doResolvePlaceholders(text, this.nonStrictHelper);
}@Override
public String resolveRequiredPlaceholders(String text) throws IllegalArgumentException {if (this.strictHelper == null) {this.strictHelper = createPlaceholderHelper(false);}return doResolvePlaceholders(text, this.strictHelper);
}/*** Resolve placeholders within the given string, deferring to the value of* {@link #setIgnoreUnresolvableNestedPlaceholders} to determine whether any* unresolvable placeholders should raise an exception or be ignored.* <p>Invoked from {@link #getProperty} and its variants, implicitly resolving* nested placeholders. In contrast, {@link #resolvePlaceholders} and* {@link #resolveRequiredPlaceholders} do <i>not</i> delegate* to this method but rather perform their own handling of unresolvable* placeholders, as specified by each of those methods.* @since 3.2* @see #setIgnoreUnresolvableNestedPlaceholders*/
protected String resolveNestedPlaceholders(String value) {if (value.isEmpty()) {return value;}return (this.ignoreUnresolvableNestedPlaceholders ?resolvePlaceholders(value) : resolveRequiredPlaceholders(value));
}private PropertyPlaceholderHelper createPlaceholderHelper(boolean ignoreUnresolvablePlaceholders) {return new PropertyPlaceholderHelper(this.placeholderPrefix, this.placeholderSuffix,this.valueSeparator, ignoreUnresolvablePlaceholders);
}private String doResolvePlaceholders(String text, PropertyPlaceholderHelper helper) {return helper.replacePlaceholders(text, this::getPropertyAsRawString);
}
可以看到最终是通过PropertyPlaceholderHelper来实现的,可以通过以下代码了解PropertyPlaceholderHelper 的作用
@Test
public void propertyPlaceholderHelper(){PropertyPlaceholderHelper propertyPlaceholderHelper = new PropertyPlaceholderHelper("{" , "}");Properties properties = new Properties();properties.put("customValue" , "孙悟空");String s = propertyPlaceholderHelper.replacePlaceholders("aaaaa {customValue} bbbbbb", properties);System.out.println(s);}运行结果:
aaaaa 孙悟空 bbbbbb
4.PropertySourcesPropertyResolver
我们最终使用的一般都是 PropertySourcesPropertyResolver
@Test
public void propertySourcesPropertyResolver() {MutablePropertySources propertySources = new MutablePropertySources();propertySources.addLast(new PropertiesPropertySource("systemProperties" , System.getProperties()));propertySources.addLast(new SystemEnvironmentPropertySource("systemEnvironment", (Map) System.getenv()));PropertySourcesPropertyResolver propertySourcesPropertyResolver = new PropertySourcesPropertyResolver(propertySources);//系统信息中包含 user.dir 这个配置 System.out.println(propertySources.get("systemProperties").getProperty("user.dir"));// 用系统信息中 user.dir 的值替换表达式的值String s = propertySourcesPropertyResolver.resolvePlaceholders("aaaa ${user.dir} ccc");System.out.println(s);}运行结果:
D:\springboot-demo\study-spring
aaaa D:\springboot-demo\study-spring ccc