Spring 中的 PropertyResolver 用来解析字符串中包含的表达式,并且用Properties对象中的值替换掉表达式

news/2024/11/7 0:23:52/

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


http://www.ppmy.cn/news/1544918.html

相关文章

高级Python自动化运维:容器安全与网络策略的深度解析

高级Python自动化运维&#xff1a;容器安全与网络策略的深度解析 目录 &#x1f512; 容器安全的基本原则&#x1f310; 网络策略的设计与实施&#x1f6e1;️ 容器映像安全扫描与漏洞管理⚙️ 实现安全的CI/CD流水线 1. &#x1f512; 容器安全的基本原则 在现代云计算环境…

嵌入式——STM32外设应用

STM32 微控制器以其高性能、低功耗和丰富的外设资源&#xff0c;在嵌入式系统设计中得到了广泛应用。以下将详细介绍 STM32 的主要外设及其典型应用&#xff0c;帮助开发者更好地理解和应用这些功能。 1. GPIO&#xff08;通用输入输出端口&#xff09; 功能&#xff1a;GPIO…

第一章:Docker 安装TDengine

Docker 安装TDengine 目标 掌握Docker 安装TDengine介绍 TDengine 是一个高性能、分布式的时序数据库,专为物联网 (IoT) 和大数据分析设计。使用 Docker Compose 可以快速地搭建 TDengine 的开发或测试环境。以下技术指南,帮助您通过 Docker Compose 安装并运行 TDengine。…

MySQL数据表导入到clickhouse数据库中

前言&#xff1a;研发需求&#xff0c;需要把MySQL数据导入到clickhouse中来测试计算性能是否提升。 从MySQL导入到clickhouse需要两个工具 NavicatDBeaver 导出MySQL数据 连接上MySQL>选择数据库>选择数据表 选择csv格式 导出数据 下面全部默认即可 开始导出 …

测试自动化如何和业务流程结合?

测试自动化框架固然重要&#xff0c;但是最终自动化的目的都是为了业务服务的。 那测试自动化如何对业务流程产生积极影响&#xff1f; 业务流程的重要性 测试自动化项目并非孤立存在&#xff0c;其生命周期与被测试的应用程序紧密相关。项目的价值在于被整个开发团队所使用&a…

华为eNSP实验:RSTP实验

一&#xff1a;RSTP与STP的介绍及对比&#xff1a; RSTP&#xff08;Rapid Spanning Tree Protocol&#xff0c;快速生成树协议&#xff09;是STP&#xff08;Spanning Tree Protocol&#xff0c;生成树协议&#xff09;的改进版本&#xff0c;旨在提高网络在拓扑变化时的收敛…

linux基础-lvm逻辑卷组分区实操

补充 分区类型 1、系统引导分区&#xff08;第0扇区&#xff09;&#xff1a;存放系统引导文件&#xff08;检测操作系统的位置&#xff09;和linux的内核文件。 2、swap分区&#xff08;交换分区&#xff09;&#xff1a;当程序运行时的物理内存不够时&#xff0c;从其他未…

vue常见题型(1-10)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 2.2双向绑定的原理是什么vue框架采用的是数据双向绑定的方式&#xff0c;由三个重要部分构成2.2.1.ViewModel2.2.2 双向绑定2.2.3.1.编译Compile2.2.3.2.依赖收集 3…