How to access property value from JVM options in Spring with some default values set in applicationContext.xml?

java, properties, spring, spring-mvc

Solution

You can make a bean which takes a map parameter from context with default values and initializes system properties

<bean class="test.B1">
    <constructor-arg>
        <map>
            <entry key="p1" value="v1" />
            <entry key="p2" value="v2" />
                                 ....
        </map>
    </constructor-arg>
</bean>

.

public B1(Map<String, String> defaultProperties) {
    for (Map.Entry<String, String> e : defaultProperties.entrySet()) {
        if (System.getProperty(e.getKey()) == null) {
            System.setProperty(e.getKey()
                    , e.getValue());
        }
    }
}

B1 definition in the context should be before any bean using `#{systemProperties.myProperty}` so that properties are initialized first

UPDATE

That was about overriding system properties. But if you only need to override Spring placeholders like here

<bean class="test.B1">
    <property name="prop1" value="${xxx}" />
</bean>

it's enough to set property-placeholder's local-override attr to "true"

<context:property-placeholder location="classpath:/app.properties" local-override="true" />

Problem

I want to access some property value passed from JVM in Spring's applicationContext.xml. One way I know to achieve this is by `#{systemProperties.myProperty}` for some `-DmyProperty=xyz` according to Spring's Expression Language feature. But I am interested in having a default value for each such property that I assign through JVM, in case the user doesn't set the value from JVM options of the server. How can I achieve this in any context xml file for Spring? Please help.

Original source