Question
I'm wondering, if there is a generic way to fill a map with properties you just know the prefix.
Assuming there are a bunch of properties like
namespace.prop1=value1
namespace.prop2=value2
namespace.iDontKnowThisNameAtCompileTime=anothervalue
I'd like to have a generic way to fill this property inside a map, something like
@Component
@ConfigurationProperties("namespace")
public class MyGenericProps {
private Map<String, String> propmap = new HashMap<String, String>();
// setter and getter for propmap omitted
public Set<String> returnAllKeys() {
return propmap.keySet();
}
}
Or is there another convenient way to collect all properties with a certain prefix, instead of iterating over all PropertySources in the environment?
Thanks Hansjoerg
Answer
As long as you're happy having every property added into the map, rather than
just those that you don't know in advance, you can do this with
@ConfigurationProperties
. If you want to grab everything that's beneath
namespace
then you need to use an empty prefix and provide a getter for a
map named namespace
:
@ConfigurationProperties("")
public class CustomProperties {
private final Map<String, String> namespace = new HashMap<>();
public Map<String, String> getNamespace() {
return namespace;
}
}
Spring Boot uses the getNamespace
method to retrieve the map so that it can
add the properties to it. With these properties:
namespace.a=alpha
namespace.b=bravo
namespace.c=charlie
The namespace
map will contain three entries:
{a=alpha, b=bravo, c=charlie}
If the properties were nested more deeply, for example:
namespace.foo.bar.a=alpha
namespace.foo.bar.b=bravo
namespace.foo.bar.c=charlie
Then you'd use namespace.foo
as the prefix and rename namespace
and
getNamespace
on CustomProperties
to bar
and getBar
respectively.
Note that you should apply @EnableConfigurationProperties
to your
configuration to enable support for @ConfigurationProperties
. You can then
reference any beans that you want to be processed using that annotation,
rather than providing an @Bean
method for them, or using @Component
to
have them discovered by component scanning:
@SpringBootApplication
@EnableConfigurationProperties(CustomProperties.class)
public class YourApplication {
// …
}