Comments (8)
Thanks, I understand now.
The documentation that you've referenced is referring to type-safe binding of configuration properties. The behavior where a list is only populated from a single source is specific to this binding and is what you get when you use @ConfigurationProperties
. When you're accessing the environment directly, as you are doing, you aren't using the type-safe binding of configuration properties so none of its behavior applies.
If you want to mimic the same behavior when accessing the environment directly, you will have to drop down a level and work with the environment's individual property sources in order. Once you find one that contains a my-prop[]
property, you'd then use it exclusively to determine all of the list's values. This is what IndexedElementsBinder
does:
The return
short-circuits the binding so that only the first source the contains items for the list is used.
If you're seeing the myProp
field of a MyConfigurationClass
instance that's been set by @ConfigurationProperties
binding contain values from multiple sources then you have found a bug. If you can provide a minimal example of it occurring we can investigate it and fix it. On the other hand, if your problem only occurs when working with the environment directly, you'll have to update your code so that it behaves in a similar manner to Boot's configuration property binding support.
from spring-boot.
I missed your most-recent comment while writing the above. Thanks for confirming that @ConfigurationProperties
is working as expected. In that case, I'm going to close this one. As you're working with the environment directly and have dropped beneath Boot's configuration properties support that builds on top of the environment, you'll have to mimic some of its functionality.
from spring-boot.
Multiple indexed property keys mapping onto the same underlying collection-based value is a feature of type-safe configuration property binding. The Environment
from Spring Framework knows nothing about this feature. As far as it's concerned my-prop[0]
, my-prop[1]
, and my-prop[2]
are three different and entirely unrelated properties.
I thought that the
getProperty
method of the SpringEnvironment
already takes into account the precedences of property sources
It does, however it's taken into account on a property-by-property basis.
from spring-boot.
Assuming I have understood the problem correctly, I think this should work as you want it to. We have some tests that verify this is the case, for example:
It's not clear where the unwanted blub
is coming from in your case as it's present both in the property's default value and in application.yml
. I'm also not sure where "the logic I use to get the value for the list property" comes into play. To remove these uncertainties, please provide a minimal sample that reproduces the problem and that uses a different value for the third element in the list in the two possible sources (its default and application.yml
).
from spring-boot.
I don't think it is necessary to use a different value for the third element.
But let me summarize what the problem is:
This is my application.yml
myProp
- machine
- articles
- blub
This is my application-dev.yml
, It has higher precedence because it is an active profile when starting the spring boot app.
myProp
- machine
- articles
Now when you want to query the value in custom logic, you have to use something like this:
springEnvironment.getProperty(...)
For lists, you have to query earch list item individually by using it's index (https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#features.external-config.yaml). Note that using springEnvironment.getProperty("my-prop")
returns null
when using the yml list syntax in properties files, So I must use the index syntax.
Bascially what my logic does is the following: Iterate over all available indices to get all list values. If an index returns null, that means for me that I have reached the end of the list.
So this is what happens in my code:
this.configurableSpringEnvironment.getProperty("my-prop[0]") --> returns machine --> correct 👍
this.configurableSpringEnvironment.getProperty("my-prop[1]") --> returns articles --> correct 👍
this.configurableSpringEnvironment.getProperty("my-prop[2]") --> returns NOT null but blub--> NOT correct 👎
Why is the last one not correct: because application-dev.yml
only contains a list with 2 entries and not 3.
Does that clarify my problem?
from spring-boot.
UPDATE:
It seems like that the binding for the @ConfigurationProperties
class works as expected. I just checked it in the debugger.
It only contains the 2 list items, machine and articles.
But the springEnvironment.getProperty()
returns false (?) values (as described in my previous post).
from spring-boot.
@wilkinsona Thank you very much for the detailed explanation. I thought that the getProperty
method of the SpringEnvironment
already takes into account the precedences of property sources. But that doesn't seem to be case in this special scenario. Wouldn't that be better/ a reason for a new issue?
Because usually the getProperty()
method returns the value with the highest precedence the spring environment contains.
For a better understanding: I have built a Config Editor for our project that enables us to alter the PropertySources and thus our @ConfigurationProperties bindings during runtime.
from spring-boot.
All right, that makes sense.
I think the best solution for me is to use reflection on @ConfigurationProperties
classes when trying to query the current value of a configuration property in a generic way (instead of using the spring environment which I use at the moment). This way I can leverage all the features of the type-safe binding of spring boot regarding @ConfigurationProperties
classes.
Thanks again for the discussion!
from spring-boot.
Related Issues (20)
- Test Gradle plugin against Gradle 8.7
- Buildpacks do not support Docker with containerd image store HOT 2
- x-www-form-urlencoded escaping leads to truncated request HOT 1
- Trigger docs build when artifacts are published
- Add caching to docs-build
- Upgrade from 3.0.13 to 3.1.10 - SSL setup through jvm properties broken HOT 3
- JDK22 and GraalVM spring-boot:3.2.4:build-image failed: Builder lifecycle 'creator' failed with status code 51 HOT 1
- Graceful Shutdown behavior ambiguity in Reference Guide
- Clarify that all named properties must match for @ConditionalOnProperty to match HOT 2
- Getting 500 instead of 404 with integration tests when updating from Spring Boot 3.1.x to to 3.2.4 HOT 6
- Bump gradle/wrapper-validation-action from 2.1.1 to 2.1.2
- Bump gradle/wrapper-validation-action from 2.1.1 to 2.1.2
- Remove redundant Regex escapes
- Remove redundant Regex escapes
- Remove redundant Regex escapes
- Verify snapshots once they have been deployed
- Verify snapshots once they have been deployed
- Verify snapshots once they have been deployed
- Upgrade to Gradle Enterprise Conventions 0.0.16
- Reference Guides breadcrumb in page headers is not hyperlinked HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from spring-boot.