Reputation: 245
I want to escape my Spring propeties file in order to get in my bean property: ${ROOTPATH}/relativePath
I have a simple Spring config file that contains:
<context:property-placeholder location="classpath:myprops.properties" />
<bean id="myBean" class="spring.MyBean">
<property name="myProperty" value="${myproperty}" />
</bean>
The myprops.properties
contains:
myproperty=\${ROOTPATH}/relativePath
The above setup returns: Could not resolve placeholder 'ROOTPATH'. I tried a lot of possible syntaxes but was not able to find the right one.
Upvotes: 19
Views: 11099
Reputation: 3633
Although it works, escaping the placeholder is super-ugly.
I achieved this my overriding PropertySourcesPlaceholderConfigurer.doProcessProperties
and using a custom 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);
}
}
plugging it into the app
@Configuration
public class PlaceHolderResolverConfig
{
@Bean
public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {
PropertySourcesPlaceholderConfigurer placeHolderConfigurer = new CustomPropertySourcesPlaceholderConfigurer();
placeHolderConfigurer.setLocation(new ClassPathResource("application.properties"));
return placeHolderConfigurer;
}
}
In the above example, for all properties starting with something.*
nested placeholders wont be resolved..
remove the if(strVal.startsWith("${something."))
check if you want the behaviour for all properties
Upvotes: 0
Reputation: 14061
Here is a Spring ticket which asks for escaping support (still unresolved at the time of writing).
The workaround of using
$=$
myproperty=${$}{ROOTPATH}/relativePath
does provide a solution, but looks quite dirty.
Using SPEL expressions like #{'$'}
did not work for me with Spring Boot 1.5.7.
Upvotes: 3
Reputation: 69
Seems so far, that is no way to escape the ${}
, however you can try below configuration to solve the problem
dollar=$
myproperty=${dollar}{myproperty}
Result for myproperty will be ${myproperty}
after evaluation.
Upvotes: 6
Reputation: 697
Instead of ${myproperty}
use #{'$'}{myproperty}
. Simply replace $
with #{'$'}
.
Upvotes: 19