我有一個屬性文件並使用Spring屬性佔位符,我將值設置爲Spring bean。現在,這個屬性文件可能在運行期間被修改。有沒有辦法用這個新修改的屬性值來刷新Spring bean的屬性?特別是,我有很多單身豆?我怎樣才能用新的價值來刷新它們?是否已有解決方案或者是否應該定製編碼?如果它不存在,有人可以給出最好的方法來實現這一目標嗎?謝謝!Spring - 用新的屬性文件值替換bean屬性值
PS:我的應用程序是批量應用程序。我使用基於Spring的Quartz配置來安排批次。
我有一個屬性文件並使用Spring屬性佔位符,我將值設置爲Spring bean。現在,這個屬性文件可能在運行期間被修改。有沒有辦法用這個新修改的屬性值來刷新Spring bean的屬性?特別是,我有很多單身豆?我怎樣才能用新的價值來刷新它們?是否已有解決方案或者是否應該定製編碼?如果它不存在,有人可以給出最好的方法來實現這一目標嗎?謝謝!Spring - 用新的屬性文件值替換bean屬性值
PS:我的應用程序是批量應用程序。我使用基於Spring的Quartz配置來安排批次。
我會離開這個爲參考,但更新的答案是分隔器下方:
嘛ConfigurableApplicationContext
接口包含一個refresh()方法,這應該是你想要的,但問題是:如何訪問該方法。
private ConfigurableApplicationContext context;
@Autowired
public void setContext(ConfigurableApplicationContext ctx){
this.context = ctx;
}
現在我建議兩個基本的選擇是要麼
ConfigurableApplicationContext
類型的依賴豆開始並讓Bean定期查看屬性資源,當它發現更改時刷新ApplicationContext或參考意見:因爲它似乎是不可能的刷新整個範圍內,另一種策略是創建一個屬性工廠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中,但是,您必須小心始終使用原型範圍。這在單身豆子裏特別棘手,a solution can be found here。
如果你不希望所有的地方注入查找方法,你也可以注入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);
}
}
這是不是加載整個應用程序上下文?你能分享一些樣品嗎?我對Spring很新,所以我可能是錯的。我也想過重新加載整個Spring應用程序上下文,但這意味着其他當前正在運行的進程可能會中斷。或者,我想錯了! – SJoe 2010-11-03 08:50:24
不,你是對的,整個上下文將被刷新。 – 2010-11-03 08:57:23
在這種情況下,我目前正在運行的進程不會中斷。我的批處理應用程序可能需要數小時才能完成一個過程。另外,我有一個通過Spring配置的SchedularFactoryBean。我的問題是,如果我完全重新加載應用程序上下文,是不是會重置計劃程序?大概是 – SJoe 2010-11-03 09:07:49