Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I've got a question for programmatically added properties to a spring context.

GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
ConfigurableEnvironment ctxEnvironment = ctx.getEnvironment();
ctxEnvironment.getPropertySources().addFirst(new ResourcePropertySource("rootProperties", new FileSystemResource("/tmp/root.properties")));
ctx.load(new ClassPathResource("/context/application-context.xml"));
ctx.refresh();

root.properties:

test=hello

Snippet from application context:

<property name="test" value="${test} world"/>

When I load the bean from the context, ${test} is not substituted with "hello".

Spring version: 5.1.5.RELEASE

What am I missing here?

PS: Btw, this works:

 System.out.println("Text: " + ctxEnvironment.resolvePlaceholders("${test}"));

Output:

 Text: hello

EDIT: Sorry, I forgot to add: I don't want to use the context:property-placeholder bean, because I know the location of the properties file only at runtime.

I'm not sure but just want to give a try <property name="test" value="${test}"+"world"/> like this – Ryuzaki L Jul 22, 2019 at 15:19 Thanks, I already tried to only use the property name in the value attribute. Didn't help. – Klaus Jul 22, 2019 at 15:29

I reproduced your case and it's working for me. You need to add a property place holder in your applicationContext.xml file :

    <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">
    <context:property-placeholder location="file:/tmp/root.properties" />
    <bean id="myA" class="com.zpavel.MyA">
        <property name="test" value="${test}" />
    </bean>
</beans>

For example a simple bean :

public class MyA {
    private String test;
    public String getTest() {
        return test;
    public void setTest(String test) {
        this.test = test;

You can load it with :

ApplicationContext context = new ClassPathXmlApplicationContext("classpath:/context/application-context.xml");
MyA myA = context.getBean(MyA.class);
System.out.println(myA.getTest());

It will print "hello" as expected.

I don't want to use the context:property-placeholder bean, because I know the location of the properties file only at runtime. – Klaus Jul 22, 2019 at 20:14 You can set the location of your file at runtime by -Dmyfile=/tmp/root.properties and then property placeholder becomes <context:property-placeholder location="file:${myfile}" /> – zpavel Jul 22, 2019 at 20:25 Thanks, that actually works, but I still need the context:property. I also want to use the properties only if available, so that would still be a little problem. Ccould use a placeholder, I know - but I found a pure programmatic approach right now. – Klaus Jul 23, 2019 at 6:54
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">
    <context:property-placeholder
        location="application.properties" />
    <bean id="demo"
        class="com.example.Demo">
        <property name="value1" value="${test} world" />
    </bean>
</beans>

application.properties :

test = Hello

Demo.java :

public class Demo {
    String value1;
    public String getValue1() {
        return value1;
    public void setValue1(String value1) {
        this.value1 = value1;
    @Override
    public String toString() {
        return value1;

Test.java :

public class Test {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext(
                "applicationContext.xml");
        Demo demo = (Demo) classPathXmlApplicationContext.getBean("demo");
        System.out.println(demo);
        classPathXmlApplicationContext.close();

When you run, the output :

Hello world

The problem is with the bean. Please check it.

I don't want to use the context:property-placeholder bean, because I know the location of the properties file only at runtime. – Klaus Jul 22, 2019 at 20:13 Ok that's fine. But I want to say that it's working fine. Some other issue may be there. Check for that – Anish B. Jul 23, 2019 at 2:56

After some more diving into the spring API I found a pure programmatic solution to my problem without the need of a context:property element. For anyone interested, here is the full source:

Test.java

  public class Test {
      public static void main(String[] args) throws Exception {
          GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
          PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
          MutablePropertySources propertySources = new MutablePropertySources();
          propertySources.addFirst(new ResourcePropertySource("rootProperties", new ClassPathResource("/root.properties")));
          configurer.setPropertySources(propertySources);
          ctx.addBeanFactoryPostProcessor(configurer);
          ctx.load(new ClassPathResource("/ctx.xml"));
          ctx.refresh();
          TestBean bean = ctx.getBean(TestBean.class);
          System.out.println(bean.getString());

TestBean.java

  public class TestBean {
      String string = "";
      public String getString() { return string; }
      public void setString(String string) { this.string = string; }

ctx.xml

  <?xml version="1.0" encoding="UTF-8"?>
  <beans xmlns="http://www.springframework.org/schema/beans"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://www.springframework.org/schema/beans classpath:/org/springframework/beans/factory/xml/spring-beans.xsd">
      <beans>
          <bean class="TestBean">
              <property name="string" value="${test} world"/>
          </bean>
      </beans>
  </beans>

root.properties

  test=hello
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.