ps-aux
ps-aux

Reputation: 12136

Set/override Spring / Spring Boot properties at runtime

At the project with Spring Boot we use application.properties but need to configure some of these properties (like port number of logging level) based on an external configuration. We access the configuration via API so it is known only at runtime.

Is there a way to override or set some Spring properties at runtime (for example using a bean) and if yes how can this be achieved?

Upvotes: 27

Views: 48435

Answers (2)

Todderz
Todderz

Reputation: 331

You could do this with Spring Cloud Config

Just for the purpose of illustration, here's a relatively quick way to see dynamic property overrides at runtime:

First, for your bean to be able to pick up changed properties, you need to annotate it with

@RefreshScope

Add the spring cloud dependency to your spring boot app, eg for gradle

compile group: 'org.springframework.cloud', name: 'spring-cloud-starter', version: '1.1.1.RELEASE'

( NB You also need the spring boot actuator dependency.)

With the app running, you can view your current config at eg

http://localhost:8080/env

eg if you have a property 'my.property' in application.properties, you'll see something like:

"applicationConfig: [classpath:/application.properties]": {
  "my.property": "value1",
  etc

To change the value, POST my.property=value2 to /env as application/x-www-form-urlencoded

eg

curl -X POST http://localhost:8080 -d my.property=value2

GET /env again and you'll see the new value appears under the "manager" section

To apply the changed properties, do an empty POST to /refresh. Now your bean will have the new value.

Upvotes: 22

rhinds
rhinds

Reputation: 10043

Could you use system properties to pass in the variable? If you configure the PropertyPlaceholderConfigurer you can set the precedence of system properties vs file properties.

For example, something like:

@Bean public PropertyPlaceholderConfigurer placeHolderConfigurer() {
    PropertyPlaceholderConfigurer props = new PropertyPlaceholderConfigurer()
    props.setSystemPropertiesMode( PropertyPlaceholderConfigurer.SYSTEM_PROPERTIES_MODE_OVERRIDE )
    props.setLocations(new 
PathMatchingResourcePatternResolver().getResources("classpath:/**.properties"));
    props
}

The above would load your .properties file, but we set the priority to be system variables first, so if you set a system variable that will override the same variable in the config.

Alternatively, looking at the docs, Spring recommends defining a search order in your Environment:

[PropertyPlaceholderConfigurer is still appropriate for use when] existing configuration makes use of the "systemPropertiesMode" and/or "systemPropertiesModeName" properties. Users are encouraged to move away from using these settings, and rather configure property source search order through the container's Environment; however, exact preservation of functionality may be maintained by continuing to use PropertyPlaceholderConfigurer.

Hopefully one of the above should sort out what you need?

Upvotes: 4

Related Questions