我有一个属性文件并使用 Spring 属性占位符,我为 Spring bean 设置了值。现在,可以在运行时修改此属性文件。有没有办法用这个新修改的属性值刷新 Spring bean 的属性?特别是,我有很多单身豆?如何使用新值刷新它们?是否已经有解决方案或者是否应该对其进行自定义编码?如果它不存在,有人可以给出实现这一目标的最佳方法吗?谢谢!
PS:我的申请是批量申请。我使用基于 Spring 的 Quartz 配置来安排批处理。
我有一个属性文件并使用 Spring 属性占位符,我为 Spring bean 设置了值。现在,可以在运行时修改此属性文件。有没有办法用这个新修改的属性值刷新 Spring bean 的属性?特别是,我有很多单身豆?如何使用新值刷新它们?是否已经有解决方案或者是否应该对其进行自定义编码?如果它不存在,有人可以给出实现这一目标的最佳方法吗?谢谢!
PS:我的申请是批量申请。我使用基于 Spring 的 Quartz 配置来安排批处理。
我将把它留作参考,但更新的答案在分隔线下方:
ConfigurableApplicationContext
接口包含一个refresh ()方法,这应该是您想要的,但问题是:如何访问该方法。无论您采用哪种方式,您都将从一个依赖于 type 的 bean 开始ConfigurableApplicationContext
:
private ConfigurableApplicationContext context;
@Autowired
public void setContext(ConfigurableApplicationContext ctx){
this.context = ctx;
}
现在我建议的两个基本选项是
参考评论:由于似乎不可能刷新整个上下文,因此另一种策略是创建一个属性工厂 bean 并将其注入所有其他 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 中,但是,您必须小心始终使用原型范围。这在单例 bean 中特别棘手,可以在此处找到解决方案。
如果你不想到处注入查找方法,你也可以PropertyProvider
像这样注入一个 bean:
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);
}
}