Я оставлю это для справки, но обновленный ответ находится ниже делителя:
Ну, а интерфейс ConfigurableApplicationContext
содержит метод refresh () , который должен быть какимВы хотите, но вопрос в том, как получить доступ к этому методу.Как бы вы это ни делали, вы начнете с компонента, который имеет зависимость типа ConfigurableApplicationContext
:
private ConfigurableApplicationContext context;
@Autowired
public void setContext(ConfigurableApplicationContext ctx){
this.context = ctx;
}
Теперь я бы предложил два основных варианта:
- используйте Framework Execution Framework и позволяйте вашему компоненту регулярно просматривать ресурсы свойств, обновляя ApplicationContext при обнаружении изменений или
- , предоставляя компоненту JMX , что позволяет вам вручную запускать обновление.
Ссылаясь на комментарии: поскольку кажется невозможным обновить весь контекст, альтернативной стратегией будет создание фабрики свойств и добавление ее ввсе остальные bean-компоненты.
public class PropertiesFactoryBean implements FactoryBean<Properties>{
public void setPropertiesResource(Resource propertiesResource){
this.propertiesResource = propertiesResource;
}
private Properties value=null;
long lastChange = -1L;
private Resource propertiesResource;
@Override
public Properties getObject() throws Exception{
synchronized(this){
long resourceModification = propertiesResource.lastModified();
if(resourceModification != lastChange){
Properties newProps = new Properties();
InputStream is = propertiesResource.getInputStream();
try{
newProps.load(is);
} catch(IOException e){
throw e;
} finally{
IOUtils.closeQuietly(is);
}
value=newProps;
lastChange= resourceModification;
}
}
// you might want to return a defensive copy here
return value;
}
@Override
public Class<?> getObjectType(){
return Properties.class;
}
@Override
public boolean isSingleton(){
return false;
}
}
Вы можете внедрить bean-компонент этого свойства во все остальные bean-компоненты, однако вам следует быть осторожным, чтобы всегда использовать область действия прототипа.Это особенно сложно внутри синглтон-бинов, решение можно найти здесь .
Если вы не хотите внедрять методы поиска повсеместно, вы также можете добавить PropertyProvider
боб, как это:
public class PropertiesProvider implements ApplicationContextAware{
private String propertyBeanName;
private ApplicationContext applicationContext;
public void setPropertyBeanName(final String propertyBeanName){
this.propertyBeanName = propertyBeanName;
}
@Override
public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException{
this.applicationContext = applicationContext;
}
public String getProperty(final String propertyName){
return ((Properties) applicationContext.getBean(propertyBeanName)).getProperty(propertyName);
}
}