Given a spring-boot project with spring-actuator

Given @SpringBootTest using @ConfigurationProperties(prefix) to remap a legacy @Value wired pojo.

CommonConfig A Common @Configuration

Unit tests covering the auto-wiring of the bean pass.

  • Initialization, Prefix Changing, Runtime Usage Runtime: Same profile(s), Same Configuration
  • Fails to initialize throwing IllegalArgumentException from the @Value.

Cause:

I have narrowed it down to the load order of property handlers: refresh() method of 1. org.springframework.web.context.support.GenericWebApplicationContext 2. org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext

The 2 pre-adds its handlers to the property binding handler. These radically alter the flow of lookup. Causing the @Value handler to come before the @ConfigurationProperties As the ConfigurationProperties is considered in the current literature to be a better method, I can think of 2 possible solutions.

Possible solution: Change the order of addition of handlers in ServletWebServerApplicationContext; however, look deeply at why the order is non-standard. This may be a tangled weave of coded and expected behaviors that may not be so easy to unwind.

Possible solution: (Due to the complexity of other downstream users like spring-data, xd, etc) Use a priority list in place of the observer linear list currently used. Then define the "Currently better approach with a higher priority" Define a weighted range of priority (more non-deterministic overall however, concrete in usage case.) {fuzzy logic example: high, medium, low.)

Then the adding order no longer forces bad behaviors.

Comment From: philwebb

I'm not totally understanding the issue as described. Could you please add a sample application that shows what you mean?

Comment From: paulkossler

Example project: ConfigurationPropertiesVsValue.zip

The Springboot test runs as expected Running that application fails Please post any clean test cases for running the application

Comment From: snicoll

@paulkossler unfortunately, that sample didn't help me to understand the issue you've described. There are a number of unrelated issues in this sample:

  • ConfigTest is in src/main/java. As such, this sample doesn't compile
  • The application does not start because UserOfValueInjectedModel fails. You're trying to inject ValueInjectedModel but two beans are contributed to the context: the one that Spring Boot provides via the standard @EnableConfigurationProperties mechanism and the user-defined produceOverriddenValueInjectedModel bean.

Please revisit this sample so that it demonstrates the issue you've described. The test should pass out of the box and the application should fail out of the box as well. If instructions are required to make that happen, please document them so that we can replicate the problem.

Comment From: spring-projects-issues

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

Comment From: spring-projects-issues

Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.