Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
288 views
in Technique[技术] by (71.8m points)

java - Using ConfigurationProperties to fill Map in generic way

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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 {
    // …
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...