简体   繁体   中英

Changing Spring Boot Properties Programmatically

I'm trying to write tests for an application that uses @RefreshScope . I would like to add a test that actually changes out properties and asserts that the application responds correctly. I have figured out how to trigger the refresh (autowiring in RefreshScope and calling refresh(...) ), but I haven't figured out a way to modify the properties. If possible, I'd like to write directly to the properties source (rather than having to work with files), but I'm not sure where to look.

Update

Here's an example of what I'm looking for:

public class SomeClassWithAProperty {
    @Value{"my.property"}
    private String myProperty;

    public String getMyProperty() { ... }
}

public class SomeOtherBean {
    public SomeOtherBean(SomeClassWithAProperty classWithProp) { ... }

    public String getGreeting() {
        return "Hello " + classWithProp.getMyProperty() + "!";
    }
}

@Configuration
public class ConfigClass {
    @Bean
    @RefreshScope
    SomeClassWithAProperty someClassWithAProperty() { ...}

    @Bean
    SomeOtherBean someOtherBean() {
        return new SomeOtherBean(someClassWithAProperty());
    }
}

public class MyAppIT {
    private static final DEFAULT_MY_PROP_VALUE = "World";

    @Autowired
    public SomeOtherBean otherBean;

    @Autowired
    public RefreshScope refreshScope;

    @Test
    public void testRefresh() {
        assertEquals("Hello World!", otherBean.getGreeting());

        [DO SOMETHING HERE TO CHANGE my.property TO "Mars"]
        refreshScope.refreshAll();

        assertEquals("Hello Mars!", otherBean.getGreeting());
    }
}

You could do this (I assume you mistakenly omitted the JUnit annotations at the top of your sample, so I'll add them back for you):

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
public class MyAppIT {

    @Autowired
    public ConfigurableEnvironment environment;

    @Autowired
    public SomeOtherBean otherBean;

    @Autowired
    public RefreshScope refreshScope;

    @Test
    public void testRefresh() {
        assertEquals("Hello World!", otherBean.getGreeting());

        EnvironmentTestUtils.addEnvironment(environment, "my.property=Mars");
        refreshScope.refreshAll();

        assertEquals("Hello Mars!", otherBean.getGreeting());
    }
}

But you aren't really testing your code, only the refresh scope features of Spring Cloud (which are already tested extensively for this kind of behaviour).

I'm pretty sure you could have got this from the existing tests for refresh scope as well.

Properties used in the application must be variables annotated with @Value. These variables must belong to a class that is managed by Spring, like in a class with the @Component annotation.

If you want to change the value of the properties file, you can set up different profiles and have various .properties files for each profile.

We should note that these files are meant to be static and loaded once, so changing them programmatically is sort of out of the scope of ther intended use. However, you could set up a simple REST endpoint in a spring boot app that modifies the file on the host's file system (most likely in the jar file you are deploying) and then calls Refresh on the original spring boot app.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM