Is there a way to specify a default property value in Spring XML?
We are using a PropertyPlaceholderConfigurer to use java properties in our Spring configuration (details here)
eg:
<foo name="port">
<value>${my.server.port}</开发者_StackOverflowvalue>
</foo>
We would like to add an additional property, but have a distributed system where existing instances could all use a default value. Is there a way to avoid updating all of our properties files, by indicating a default value in the Spring config for when there isn't an overriding property value defined?
Spring 3 supports ${my.server.port:defaultValue}
syntax.
There is a little known feature, which makes this even better. You can use a configurable default value instead of a hard-coded one, here is an example:
config.properties:
timeout.default=30
timeout.myBean=60
context.xml:
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>config.properties</value>
</property>
</bean>
<bean id="myBean" class="Test">
<property name="timeout" value="${timeout.myBean:${timeout.default}}" />
</bean>
To use the default while still being able to easily override later, do this in config.properties:
timeout.myBean = ${timeout.default}
<foo name="port">
<value>${my.server.port:8088}</value>
</foo>
should work for you to have 8088 as default port
See also: http://blog.callistaenterprise.se/2011/11/17/configure-your-spring-web-application/
Are you looking for the PropertyOverrideConfigurer documented here
http://static.springsource.org/spring/docs/2.5.x/reference/beans.html#beans-factory-overrideconfigurer
The PropertyOverrideConfigurer, another bean factory post-processor, is similar to the PropertyPlaceholderConfigurer, but in contrast to the latter, the original definitions can have default values or no values at all for bean properties. If an overriding Properties file does not have an entry for a certain bean property, the default context definition is used.
The default value can be followed with a :
after the property key, e.g.
<property name="port" value="${my.server.port:8080}" />
Or in java code:
@Value("${my.server.port:8080}")
private String myServerPort;
See:
valueSeparator
(fromAbstractPropertyResolver
)and
VALUE_SEPARATOR
(fromSystemPropertyUtils
)
BTW, the Elvis Operator is only available within Spring Expression Language (SpEL),
e.g.: https://stackoverflow.com/a/37706167/537554
http://thiamteck.blogspot.com/2008/04/spring-propertyplaceholderconfigurer.html points out that "local properties" defined on the bean itself will be considered defaults to be overridden by values read from files:
<bean id="propertyConfigurer"class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location"><value>my_config.properties</value></property>
<property name="properties">
<props>
<prop key="entry.1">123</prop>
</props>
</property>
</bean>
Also i find another solution which work for me. In our legacy spring project we use this method for give our users possibilities to use this own configurations:
<bean id="appUserProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="ignoreResourceNotFound" value="false"/>
<property name="locations">
<list>
<value>file:./conf/user.properties</value>
</list>
</property>
</bean>
And in our code to access this properties need write something like that:
@Value("#{appUserProperties.userProperty}")
private String userProperty
And if a situation arises when you need to add a new property but right now you don't want to add it in production user config it very fast become a hell when you need to patch all your test contexts or your application will be fail on startup.
To handle this problem you can use the next syntax to add a default value:
@Value("#{appUserProperties.get('userProperty')?:'default value'}")
private String userProperty
It was a real discovery for me.
精彩评论