Spring – 使用新的Property File值替换bean属性值

我有一个属性文件并使用Spring属性占位符,我将值设置为Spring bean。 现在,可以在运行时修改此属性文件。 有没有办法用这个新修改的属性值刷新Spring bean的属性? 特别是,我有很多单身豆? 如何使用新值刷新它们? 是否已有解决方案或是否应该自定义编码? 如果它还不存在,有人可以提供最佳方法来实现这一目标吗? 谢谢!

PS:我的应用程序是批处理应用程序。 我使用基于Spring的Quartz配置来安排批次。

我将把它留给参考,但更新的答案在分频器下面:

那么ConfigurableApplicationContext接口包含一个refresh()方法,它应该是你想要的,但问题是:如何访问该方法。 无论您采用哪种方式,都将从具有ConfigurableApplicationContext类型依赖关系的bean开始:

 private ConfigurableApplicationContext context; @Autowired public void setContext(ConfigurableApplicationContext ctx){ this.context = ctx; } 

现在,我建议的两个基本选项是

  1. 使用任务执行框架 ,让bean定期监视属性资源,在发现更改时刷新ApplicationContext
  2. 将bean公开给JMX ,允许您手动触发刷新。

参考注释:由于似乎无法刷新整个上下文,因此另一种策略是创建属性工厂bean并将其注入所有其他bean。

 public class PropertiesFactoryBean implements FactoryBean{ 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); } }