简体   繁体   中英

Spring Boot context created programmatically does not set typesafe configuration properties

We're moving our huge application to Spring Boot at the moment which works very well for our production code. Unfortunately we also have to adapt all tests. We want to keep changes as little as possible here for now and try to only rewrite the one big factory class nearly every test uses to create instances of common classes. Because objects are created by method call we are forced to create a context programmatically. We've managed it to get insertion of properties to fields annotated with @Value working, but it does not work for the new way Spring Boot introduces ( typesafe configuration properties ).

Here a little example which illustrates the problem:

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
PropertySourcesPlaceholderConfigurer propertiesPostProcessor = new PropertySourcesPlaceholderConfigurer();
ropertiesPostProcessor.setLocation(new ClassPathResource("config/test.properties"));
context.addBeanFactoryPostProcessor(propertiesPostProcessor);
context.register(PropertyTest.class);
context.refresh();

PropertyTest bean = context.getBean(PropertyTest.class);
System.out.println("value="+bean.getValue());
System.out.println("valueTypesafe="+bean.getValueTypesafe());

PropertyTest class:

@Configuration
@ConfigurationProperties(prefix = "test")
@EnableConfigurationProperties
public class PropertyTest {
    @Value("${test.value}")
    private String value;

    private String valueTypesafe;

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    public String getValueTypesafe() {
        return valueTypesafe;
    }

    public void setValueTypesafe(String valueTypesafe) {
        this.valueTypesafe = valueTypesafe;
    }
}

test.properties

test.value="works"
test.valueTypesafe="works"
valueTypesafe="works"

output:

value="works"
valueTypesafe=null

We've also tried several variations of this (other annotations, contexts, etc.), but nothing worked. I've tried to find out how Spring Boot does it, but ended up in EnableConfigurationPropertiesImportSelector and ConfigurationPropertiesBindingPostProcessor , where we did not managed it to integrate them into our context.


Solution

We've finally managed it by touching every test and adding @SpringApplicationConfiguration . Thus not creating the context manually. The programmatically way did not work and would have had other disadvantages as well.

Short answer is that you're not using Spring Boot. If you want to use those features, you need to let Spring Boot create the context of your application for you. Check SpringApplication and SpringApplicationBuilder . In test scenario, check SpringApplicationConfiguration .

@ConfigurationProperties annotated POJO are processed against the Environment and your code above does not initialize it properly. You may want to have a look at EnvironmentTestUtils and how it's used in the Spring Boot test suite.

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