In a SpringBoot application, how to set @ConfigurationProperties(prefix = ...) dynamically?

I wrote a small application which includes a @ConfigurationProperties(prefix = ...) annotation to load the correct configuration for one of the beans. This has been working fine and I've been manually changing the prefix value in my IDE as needed when testing against different environments.

Now I need to clean this up and ensure the application can run in different environments without a recompile. The value needs to be parameterized. How can I set the prefix dynamically at run-time?

Related Questions

This other question references a specific approach which doesn't work, using spEL:

Property in @ConfigurationProperties prefix

and this one says you can't use it YAML (which I don't care about)

How to implement dynamic @ConfigurationProperties Prefix

I'm looking more generally, for any working solution.

1 answer

  • answered 2018-11-08 05:57 Mark Bramnik

    I think that what you're asking for kind of contradicts spring/ spring boot practices.

    Configuration Properties keys have to be static in spring.

    This means, that in all environments the same configuration property key must exist.

    What changes is a value of the property depending on the environment

    For local development you might want to resolve:

    Example:

    my.db.host = localhost
    

    For Production however, you'll want something like:

    my.db.host = myproduction.db.host.real.address.goes.here
    

    From Spring's standpoint you have:

    @ConfigurationProperties(prefix="my.db") 
    class MyDbProperties {
       String host;
       ...
    }
    

    Now the question is how to alter the properties sets of values for dev/stage/local/production etc.

    The spring's answer is "profiles"

    In spring boot you can start the application with:

    --spring.profiles.active=dev
    

    In this case, the application-dev.properties will load automatically (or yaml of course)

    So you should create, say, one file per environment and put specific values there:

    application-local.properties

    my.db.host=localhost
    

    application-prod.properties

    my.db.host=myproduction.db.host.real.address.goes.here