Как перезагрузить свойства с помощью Spring?
Я использую файл свойств с Spring 3. Когда Spring инициализирует свой contex, он загружает файл свойств и помещает его во все бобы с аннотацией @Value.
Я хочу иметь возможность обновить некоторые свойства в файле и предоставить JMX на сервере, который перезагрузит новые свойства для Spring - без перезагрузки сервера и перезагрузки его контекста.
могу ли я реализовать это, используя некоторые Весна способ для перезагрузки свойств и заселить их всеми бобами, или я должен написать что-то подобное самостоятельно?
6 ответов
Я бы предложил заменить java.util.Properties
с PropertiesConfiguration
С Конфигурация Apache Commons. Он поддерживает автоматическую перезагрузку либо путем обнаружения изменений файла, либо путем запуска через JMX.
Я думаю, что нет единого способа сделать это. Самым "чистым" было бы закрыть весенний контекст и построить его с нуля. Например, рассмотрите возможность использования пула соединений DBCP и обновления URL-адреса подключения к базе данных. Это означает, что пул должен быть правильно закрыт, затем должен быть создан новый объект, а затем все ссылки на пул также должны быть обновлены. Теперь некоторые бобы могут принимать соединение из этого пула, а обновление конфигурации пула означает, что вам нужно как-то повторно запросите соединения. Таким образом, бобы, возможно, должны знать, как это сделать, что не является общим.
Я бы предложил создать отдельный компонент с событиями конфигурации и обновления и поместить этот компонент в зависимость для всех компонентов, которые вам нужно знать об изменениях конфигурации. Затем вы можете использовать конфигурацию Apache Commons Для изменения файлов waching и распространения обновлений конфигурации.
возможно, использование JMS хорошо (если вы позже собираетесь распространять свое приложение).
Да, вы можете сделать это весной JMX способом. Добавьте эти компоненты в файл конфигурации spring. Создайте отдельный метод для чтения файла свойств. В этом примере я использую метод callThisAgain ().
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="beans">
<map>
<entry key="your.package.bean:name=sampleBeanService" value-ref="sampleService"/>
</map>
</property>
<property name="assembler">
<bean class="org.springframework.jmx.export.assembler.MethodNameBasedMBeanInfoAssembler">
<property name="managedMethods">
<value>
callThisAgain <!--Simply declare the method name here (only the name) -->
</value>
</property>
</bean>
</property>
</bean>
<bean class="org.springframework.jmx.support.ConnectorServerFactoryBean" depends-on="rmiRegistry">
<property name="objectName" value="connector:name=rmi"/>
<property name="serviceUrl" value="service:jmx:rmi://127.0.0.1/jndi/rmi://127.0.0.1:11000/sample"/>
</bean>
<bean id="rmiRegistry" class="org.springframework.remoting.rmi.RmiRegistryFactoryBean">
<property name="port" value="11000"/>
</bean>
после этого вы можете использовать jconsole для перезагрузки метода без перезапуска сервера.
используйте apache common с spring следующим образом:
@Component
public class ApplicationProperties {
private PropertiesConfiguration configuration;
@PostConstruct
private void init() {
try {
String filePath = "/opt/files/myproperties.properties";
System.out.println("Loading the properties file: " + filePath);
configuration = new PropertiesConfiguration(filePath);
//Create new FileChangedReloadingStrategy to reload the properties file based on the given time interval
FileChangedReloadingStrategy fileChangedReloadingStrategy = new FileChangedReloadingStrategy();
fileChangedReloadingStrategy.setRefreshDelay(60*1000);
configuration.setReloadingStrategy(fileChangedReloadingStrategy);
} catch (ConfigurationException e) {
e.printStackTrace();
}
}
public String getProperty(String key) {
return (String) configuration.getProperty(key);
}
public void setProperty(String key, Object value) {
configuration.setProperty(key, value);
}
public void save() {
try {
configuration.save();
} catch (ConfigurationException e) {
e.printStackTrace();
}
}
}
Apache предоставляет нам утилиту для использования загружаемого файла свойств.
<bean id="propertiesReloadingStrategy" class="org.apache.commons.configuration.reloading.FileChangedReloadingStrategy">
<property name="refreshDelay" value="30000" /> <!-- 30 seconds -->
</bean>
<bean id="reloadableProperties" class="org.apache.commons.configuration.PropertiesConfiguration">
<constructor-arg value="file:/web/${weblogic.Domain}/${weblogic.Name}/${app.Name}/reloadable_cfg/Reloadable.properties"/>
<property name="reloadingStrategy" ref="propertiesReloadingStrategy"/>
</bean>
в то время как некоторые здесь предлагают использовать внешний способ использования свойств(внешний для собственного способа использования файлов свойств Spring). Этот ответ именно то, что вы ищетеhttps://stackoverflow.com/a/52648630/39998 свойства горячей перезагрузки в Spring Boot и Java EE.