【发布时间】:2015-10-20 10:14:41
【问题描述】:
我希望能够定期检查一些属性文件并相应地在我的应用中应用更改。
在我的 java-spring 应用程序中,我定期检查从文件系统加载的属性文件是否已更改:
Resource propsResource = new FileSystemResource("/path/to/properties/file");
File propertiesFile = propsResource.getFile();
long currentTimeStamp = propertiesFile.lastModified();
if (currentTimeStamp != lastModified) {
//File Changed
}
如果它发生了变化,我想重新加载我的 spring bean,因为它们中的一些实际上是加载 conditionally 中继属性文件中的属性值。
使用refresh 方法没有成功,所以我实际上是在调用close 方法并重新创建我的上下文:
context.close();
context = new AnnotationConfigApplicationContext(AppConfig.class);
这可以解决问题。我的问题是我有一些包含缓存数据的 bean,我不想丢失这些数据。 一种解决方案是继续使用此方法,但确保我的缓存数据驻留在不受 spring 管理的类中(静态或由我管理的单例)。
另一种解决方案可能是在重新创建上下文之前复制我的缓存数据,然后将其设置回新创建的 bean(那些保存缓存数据的 bean),但这感觉超级难看。
有更好的方法吗?
【问题讨论】:
-
问题是注入的 bean 占用了父 bean 的范围。前任您将原型注入单例。因此这导致更改配置不生效。我认为您应该仔细研究一下spring aop proxing。你可以用它做的是你可以注入代理bean并在配置更改时替换代理内部的原始对象。
-
大部分 bean 应该重新加载,只有少数不应该
-
很难预测所有细微差别,但一般来说,您可以通过使用额外的 applicationContext 来拆分不应该重新加载的“静态”bean 和“动态”。您可以使用 AbstractApplicationContext#setParent 方法来创建层次结构。在顶部(父)上下文中应该驻留具有缓存的 bean,而较低(子)上下文将被重新启动/重新加载或如此
-
这听起来很有趣(而且很有创意!)。我确实知道一个上下文(父级)导入另一个(子级)的概念,但我不熟悉另一个方向的含义,即使用“setParent”方法设置子级的父级。我会试一试!
-
@Babur 我在实现您的解决方案时遇到了问题,因为我无法创建“子”上下文,它依赖于“父”上下文,因为应用程序 bean 依赖于保存我的缓存数据的 bean。一旦我为子上下文调用“new”关键字,它自然会崩溃。
标签: java spring spring-environment