15

I have a spring-boot application. Under the run folder, there is an additional config file:

dir/config/application.properties

When the applications starts, it uses the values from the file and injects them into:

@Value("${my.property}")
private String prop;

Question: how can I trigger a reload of those @Value properties? I want to be able to change the application.properties configuration during runtime, and have the @Value fields updated (maybe trigger that update by calling a /reload servlet inside the app).

But how?

membersound
  • 81,582
  • 193
  • 585
  • 1,120
  • Have you looked here http://stackoverflow.com/questions/27919270/set-override-spring-spring-boot-properties-at-runtime? – hzitoun Oct 27 '16 at 15:06
  • 2
    `spring-cloud` with `@RefreshScope` on the `@Service` and running POST requests on `localhost:8080/my-app/refresh` on a property change solved it. – membersound Nov 02 '16 at 11:29
  • Basically you don't 'reload' values wired with @Value. But you can obtain a similar behavior using something like this https://stackoverflow.com/a/52648630/39998 – David Hofmann Oct 04 '18 at 14:21
  • https://github.com/jamesmorgan/ReloadablePropertiesAnnotation – OhadR Mar 25 '19 at 13:11

1 Answers1

7

Use the below bean to reload config.properties every 1 second.

@Component
public class PropertyLoader {

    @Autowired
    private StandardEnvironment environment;

    @Scheduled(fixedRate=1000)
    public void reload() throws IOException {
        MutablePropertySources propertySources = environment.getPropertySources();
        PropertySource<?> resourcePropertySource = propertySources.get("class path resource [config.properties]");
        Properties properties = new Properties();
        InputStream inputStream = getClass().getResourceAsStream("/config.properties");
        properties.load(inputStream);
        inputStream.close();
        propertySources.replace("class path resource [config.properties]", new PropertiesPropertySource("class path resource [config.properties]", properties));
    }
}

Your main config will look something like :

@EnableScheduling
@PropertySource("classpath:/config.properties")
public class HelloWorldConfig {
}

The instead of using @Value, each time you wanted the latest property you would use

environment.get("my.property");

Note

Although the config.properties in the example is taken from the classpath, it can still be an external file which has been added to the classpath.

Essex Boy
  • 7,565
  • 2
  • 21
  • 24
  • 1
    I've derived code from your answer into something a little more general. Hope it helps https://stackoverflow.com/a/52648630/39998 – David Hofmann Oct 04 '18 at 14:20
  • 3
    This doesn't answer the question about making @Value have new properties. I would expect that there must be a way for a prototype bean to be reloaded with new properties. I would be shocked if there was not. – Trenton D. Adams Mar 22 '20 at 04:48