Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve documentation around relaxed binding, @Value, and the canonical form of properties #20507

Closed
asarkar opened this issue Mar 12, 2020 · 5 comments
Labels
type: documentation A documentation update
Milestone

Comments

@asarkar
Copy link

asarkar commented Mar 12, 2020

@SpringBootApplication
@EnableConfigurationProperties(DemoProperties.class)
public class DemoApplication implements CommandLineRunner {
    @Value("${demo.itemPrice:3}")
    private int itemPrice = 2;
    @Autowired
    private DemoProperties demoProperties;

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @Override
    public void run(String... args) {
        System.out.printf("Item price from @Value: %d%n", itemPrice);
        System.out.printf("Item price from @ConfigurationProperties: %d%n", demoProperties.getItemPrice());
    }
}
@ConfigurationProperties(prefix = "demo")
public class DemoProperties {
    private int itemPrice = 1;

    public int getItemPrice() {
        return itemPrice;
    }

    public void setItemPrice(int itemPrice) {
        this.itemPrice = itemPrice;
    }
}

If an environment variable DEMO_ITEM_PRICE=4 is set, we get:

Item price from @Value: 3
Item price from @ConfigurationProperties: 4

If an environment variable DEMO_ITEMPRICE=4 is set, (disregarding Camel case) we get:

Item price from @Value: 4
Item price from @ConfigurationProperties: 4

Verified with 2.1.2.RELEASE. See attached demo app.
demo.zip

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Mar 12, 2020
@spencergibb
Copy link
Member

What if you do this?

@Value("${demo.item-price:3}")

@asarkar
Copy link
Author

asarkar commented Mar 12, 2020

@spencergibb @Value("${demo.item-price:3}") seems to work as expected.

@spencergibb
Copy link
Member

That's because boot now translates external configuration into a canonical format, in this case, demo.item-price. Applications need to use that form in places like the value annotations or conditional on property. External configuration can use relaxed forms. Pretty sure this is documented

@asarkar
Copy link
Author

asarkar commented Mar 12, 2020

@spencergibb Perhaps you're referring to this part of the docs 24.7.5 @ConfigurationProperties vs. @Value.

I believe it's misleading in the sense that it states @Value doesn't support relaxed binding, but as we can see, it does, but only limited to the dashed notation. I think it'll help to provide some examples to avoid this sort of confusion, or recommend in the docs that people strictly use underscores in env var only to replace a ..

@wilkinsona
Copy link
Member

The section of the documentation to which you have linked advises against using @Value with environment variables:

Please also be aware that since @Value does not support relaxed binding, it isn’t a great candidate if you need to provide the value using environment variables.

Relaxed binding is a featured of Spring Boot's binder which is only using with @ConfigurationProperties and isn't involved at all when @Value is used. It works with demo.item-price not because of relaxed binding but because of the translation to the canonical form that @spencergibb has described above. In short, the statement that @Value does not supported relaxed binding is technically accurate although I can see where the confusion has arisen.

Let's use this issue to see if we can clarify the documentation a bit.

@wilkinsona wilkinsona added type: documentation A documentation update and removed status: waiting-for-triage An issue we've not yet triaged labels Mar 12, 2020
@wilkinsona wilkinsona changed the title @ConfigurationProperties and @Value behave differently when binding Camel case properties Improve documentation around relaxed binding, @Value, and the canonical form of properties Mar 12, 2020
@wilkinsona wilkinsona added this to the 2.1.x milestone Mar 12, 2020
philwebb added a commit that referenced this issue Apr 23, 2020
Close gh-20507 in 2.3.0.RC1
@philwebb philwebb modified the milestones: 2.1.x, 2.1.14 Apr 23, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: documentation A documentation update
Projects
None yet
Development

No branches or pull requests

5 participants