Skip to content
Advertisement

Dynamically update the @value annotated fields in spring

I am trying to dynamically update the @value annotated fields in my application.

First of all, this application has a custom property source, with source being a Map<Object, String>. A timer is enabled to update the values after a minute interval.

JavaScript

Initial values of source Map<String, Object> is supplied from the PropertySourceLocator. (This is not the real scenario, but I am trying to recreate the logic used here)

JavaScript

RestController class where I inject these properties using @Value is given below. environment.getProperty("prop1"); is supplying updated value, but not the @value annotated fields. I also tried to inject a new property source updatedMap using the addFirst method of environment.propertySources() assuming that it will take precedence over the others. But that effort also went futile. any clue is much appreciated.

JavaScript

If you think this is not the right way of injecting values to a RestController, please let me know. All possible alternate suggestions/best practices are accepted.

Advertisement

Answer

Thank you @flaxel. I used @RefreshScope to resolve this issue. Posting the solution here if it helps someone with the same query.

In this particular case, I applied @RefreshScope on my Controller to refresh the bean with new values.

You can refer to this link before applying @RefreshScope to your bean.

It is the spring boot actuator that facilitates this refresh mechanism. So in order for this to work, you must have actuator in your classpath.

JavaScript

Then as discussed earlier, add RefreshScope to the bean that needs to be refreshed.

Finally, invoke the actuator/refresh endpoint to trigger the refresh.

If you want to programmatically do it, Autowire an instance of RefreshEndpoint class to your bean and invoke the refresh() method in it. [Note: You don’t have to strictly follow this approach, but I am giving a clue that it can be Autowired]

JavaScript

**************** MORE (if you are developing a library) ********************

What if you are developing a library and you have to get the RefreshEndpoint instance from the current ApplicationContext?

Simply Autowiring RefreshEndpoint may give you a null reference. Instead, you can get hold of the current ApplicationContext by the method given below. And use the ApplicationContext to get the RefreshEndpoint instance to invoke the refresh() method on it.

JavaScript

Finally, add this class to the spring.factories to get invoked by spring.

JavaScript
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement