I'm using Spring Boot and I have a properties file p.properties:
p1 = some val1
p2 = some val2
Configuration class:
@Configuration
@PropertySource("classpath:p.properties")
public class myProperties {
public myProperties () {
super();
}
@Bean
public static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
And I'm using this in order to access the property:
@Value("${p1}")
private String mProperty;
Everything works great. I want to change p1 in p.properties file from outside of the app and the next time that I'll use mProperty, it will contains the new value without restarting the app. Is it possible?
Thanks, Avi
I'm afraid that is not possible. The main reason you can't do this is because many of the components have a special lifecycle , so even if you change the values in properties file you would need to stop and start the respective components so all the previous resources are released and new ones acquired.
For Reloading properties, spring cloud has introduced @RefreshScope annotation which can be used for refreshing beans. Spring Actuator provides different endpoints for health, metrics. but spring cloud will add extra end point /refresh to reload all the properties.
You can do something like reading the properties file using FileInputStream into a Properties object. Then you will be able to update the properties.
You can simply use spring boot actuator
.
Just add the actuator dependency in your maven/gradle config
and you should be seeing live reloads when you update the property
file.
Note: You won't have to restart the app but actuator will do live reloads
on its own.
If you want to change the properties at runtime and don't want to restart the server then follow the below steps:
Application.properties
app.name= xyz
management.endpoints.web.exposure.include=*
Add below dependencies in pom.xml
org.springframework.boot spring-boot-starter-actuator org.springframework.cloud spring-cloud-context 2.0.1.RELEASE3)Place application.properties in config folder . The config folder must be in the location from where you will run the jar.
Add ApplcationProperties.java
@RefreshScope @Component @ConfigurationProperties(prefix = "app") public class ApplcationProperties { private String name; //getter and setter }
Write ApplicationController.java and inject ApplcationProperties
@Autowired ApplcationProperties applcationProperties;
@RestController public Class ApplicationController { @GetMapping("/find") String getValue() { return applicationProperties.getName(); } }
Run the spring boot application
Call localhost:XXXX/find
from your browser
Output : xyz
Change the value in application.properties from xyz to abc
Using postman send a put /options request to localhost:XXXX/actuator/refresh
--Note this request should be either PUT/OPTIONS
Call localhost:XXXX/find
from your browser
Output : abc
I think, in this case, it is advisable to keep it in the database so that, it can be changed & accessed seamlessly. We have a similar scenario where we keep the encrypted password for database in the properties file. While connecting to db, it needs to be decrypted. We do that by extending PropertyPlaceholderConfigurer
as follows.
public class MyPropertyConfigurer extends PropertyPlaceholderConfigurer{
protected void convertProperties(Properties props){
Enumeration<?> propertyNames = props.propertyNames();
while (propertyNames.hasMoreElements()) {
String propertyName = (String) propertyNames.nextElement();
String propertyValue = props.getProperty(propertyName);
if(propertyName.indexOf("db.password") != -1){
decryptAndSetPropValue(props,propertyName,propertyValue);
}
}
}
}
But, this is done only once while loading the properties file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With