Ответ 1
Я предлагаю заменить java.util.Properties
на PropertiesConfiguration
из проекта Apache Commons Configuration. Он поддерживает автоматическую перезагрузку либо путем обнаружения изменений файла, либо путем запуска через JMX.
Я использую файл свойств с Spring 3. Когда Spring инициализирует свой contex, он загружает файл свойств и помещает его во все beans с аннотацией @Value.
Я хочу иметь возможность обновлять некоторые свойства в файле и выставлять JMX на сервере, который перезагрузит новые свойства до Spring - без перезапуска сервера и перезагрузки его контекста.
Могу ли я реализовать это с помощью некоторого Spring метода, чтобы перезагрузить свойства и заполнить их для всех beans, или я должен написать что-то вроде этого своим?
Я предлагаю заменить java.util.Properties
на PropertiesConfiguration
из проекта Apache Commons Configuration. Он поддерживает автоматическую перезагрузку либо путем обнаружения изменений файла, либо путем запуска через JMX.
Я думаю, что нет общего способа сделать это. Самым "чистым" было бы закрыть контекст Spring и построить его с нуля. Например, рассмотрите возможность использования пула соединений DBCP и обновления его URL-адреса подключения к базе данных. Это означает, что пул должен быть правильно закрыт, затем должен быть создан новый объект, а затем все ссылки на пул также должны быть обновлены. Теперь некоторые из beans могут подключиться к этому пулу, а обновление конфигурации пула означает, что вам нужно как-то повторно запросить подключения. Таким образом, beans может понадобиться знать, как это сделать, что не является общим.
Я предлагаю создать отдельный bean с событиями конфигурации и обновления и поместить этот bean в качестве зависимости для всех beans, вам нужно знать о изменениях конфигурации. Затем вы можете использовать конфигурацию Apache Commons для изменения файлов и распространения обновлений.
Возможно, использование JMS является хорошим (если позже вы распространяете свое приложение).
Да, вы можете сделать это в стиле Spring JMX. Добавьте эти beans в конфигурационный файл 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>