Search code examples
javaspringspring-cloudspring-cloud-config

@RefreshScope with different *.properties files


I want to reload multiple config files when the refresh endpoint is called. It works perfectly fine with the entries in the application.properties file. Any other file does not refresh.

Here a small example:

pom.xml

...
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>2.3.3.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
        <version>2.3.3.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter</artifactId>
        <version>2.2.4.RELEASE</version>
    </dependency>
</dependencies>
...

application.properties

greeting=Hi
management.endpoints.web.exposure.include=refresh

test.properties

test=Test

ConfigFileHolder1

@Repository
@PropertySource(value="application.properties")
@RefreshScope
public class ConfigFileHolder1 {
    @Value("${greeting}")
    private String greeting;
    
    public String getGreeting() {
        return greeting;
    }
}

ConfigFileHolder2

@Repository
@PropertySource(value="test.properties")
@RefreshScope
public class ConfigFileHolder2 {
    
    @Value("${test}")
    private String test;
    
    public String getTest() {
        return test;
    }
}

ApiController

@Controller
@RefreshScope
public class ApiController implements Api {

    @Autowired
    private ConfigFileHolder1 config1;
    
    @Autowired
    private ConfigFileHolder2 config2;

   // do something with config1 and config2
   ...
}

Only ConfigFileHolder1 will refresh its value after the refresh-endpoint is called. To refresh the value of ConfigFileHolder2 the application has to restart.

What do I have to change to refresh the values of all my config-files/ConfigFileHolder?

Thanks for your help.


Solution

  • The @RefreshScope will only work with the properties loaded by Spring Boot, not the @PropertySources loaded later in the process. Hence you will need to tell Spring Boot to load the additional configuration files.

    You can do this by either adding names (spring.config.name) or locations spring.config.additional-location.

    When specifying an additional name make sure to include the default application as well else that won't be loaded anymore.

    --spring.config.name=application,test
    

    When specifying the above as a parameter all locations will be checked for both an application.properties and test.properties and also the expansion for profiles will be applied.

    --spring.config.additional-location=classpath:test.properties
    

    This will only load the test.properties from the class path and will make it more or less impossible to change the file at runtime but the file will be loaded from that exact location. No profile expansion will be applied.