Spring 属性文件中的转义属性引用

Posted

技术标签:

【中文标题】Spring 属性文件中的转义属性引用【英文标题】:Escape property reference in Spring property file 【发布时间】:2012-10-21 04:06:12 【问题描述】:

我想转义我的 Spring 属性文件以获取我的 bean 属性:$ROOTPATH/relativePath

我有一个简单的 Spring 配置文件,其中包含:

<context:property-placeholder location="classpath:myprops.properties" />

<bean id="myBean" class="spring.MyBean">
    <property name="myProperty" value="$myproperty" />
</bean> 

myprops.properties 包含:

myproperty=\$ROOTPATH/relativePath

上述设置返回:无法解析占位符“ROOTPATH”。我尝试了很多可能的语法,但无法找到正确的语法。

【问题讨论】:

一年没有任何评论。您解决了这个问题吗? 【参考方案1】:

使用#'$'myproperty 代替$myproperty。只需将$ 替换为#'$'

【讨论】:

不,这行不通。它将解析为 $myproperty 注入 myBean.myProperty ,而不是 $ROOTPATH/relativePath 取决于您想要实现的目标。我想你需要把它当作 myProperty 的值。如果您想从某处解析 ROOTPATH,例如您可以使用 Spring Expression Language SpEl 的系统属性。例如这样的:# systemProperties['ROOTPATH'] /relativePath【参考方案2】:

目前看来,这是无法逃脱$,但是您可以尝试以下配置来解决问题

dollar=$

myproperty=$dollarmyproperty

评估后,myproperty 的结果将是 $myproperty

【讨论】:

【参考方案3】:

Here 是 Spring 票证,它要求转义支持(在撰写本文时仍未解决)。

使用的解决方法

$=$
myproperty=$$ROOTPATH/relativePath

确实提供了解决方案,但看起来很脏。

使用像 #'$' 这样的 SPEL 表达式不适用于 Spring Boot 1.5.7。

【讨论】:

【参考方案4】:

虽然它有效,但是转义占位符是超级丑陋的。

我通过覆盖PropertySourcesPlaceholderConfigurer.doProcessProperties 并使用自定义StringValueResolver 实现了这一目标

 public static class CustomPropertySourcesPlaceholderConfigurer extends PropertySourcesPlaceholderConfigurer 

    @Override
    protected void doProcessProperties(ConfigurableListableBeanFactory beanFactoryToProcess, StringValueResolver valueResolver) 
        StringValueResolver customValueResolver = strVal -> 
            if(strVal.startsWith("$something.")) 
                PropertySourcesPropertyResolver customPropertySourcesPropertyResolver = new PropertySourcesPropertyResolver(this.getAppliedPropertySources());
                String resolvedText = customPropertySourcesPropertyResolver.resolvePlaceholders(strVal);

                //remove the below check if you are okay with the property not being present (i.e remove if the property is optional)
                if(resolvedText.equals(strVal)) 
                    throw new RuntimeException("placeholder " + strVal + " not found");
                
                return resolvedText;
            
            else 
                //default behaviour
                return valueResolver.resolveStringValue(strVal);
            
        ;
        super.doProcessProperties(beanFactoryToProcess, customValueResolver);
    

将其插入应用程序

@Configuration
public class PlaceHolderResolverConfig

  @Bean
  public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() 
     PropertySourcesPlaceholderConfigurer placeHolderConfigurer = new CustomPropertySourcesPlaceholderConfigurer();
     placeHolderConfigurer.setLocation(new ClassPathResource("application.properties"));
    
     return placeHolderConfigurer;
  

在上面的例子中,对于所有以something.* 开头的属性,嵌套的占位符都不会被解析。 删除 if(strVal.startsWith("$something.")) 检查是否需要所有属性的行为

【讨论】:

以上是关于Spring 属性文件中的转义属性引用的主要内容,如果未能解决你的问题,请参考以下文章

如何转义属性文件键中的特殊字符?

属性过滤中的转义字符(Maven)

Spring配置中的bean直接引用其它bean的属性值

如何使用 Gradle 自动转义 Java 属性文件中的 unicode 字符?

通过Spring配置文件中bean中的property赋值

Spring Boot 之属性读写详解