【问题标题】:Reload spring beans excluding some beans重新加载弹簧豆,不包括一些豆子
【发布时间】: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


【解决方案1】:

我宁愿不只是自己重新加载上下文文件,而是让 jvm 来处理它。

对于您面临的问题,您可能需要查看 Jdk 1.7 及更高版本中提供的 Watcher 服务。它的作用是检查特定目录中的文件是否被修改,如果被修改,您可以覆盖该方法来做您想做的事情。

Watcher service in jdk 1.7

【讨论】:

  • 也许我理解错了,但您的回答如何解决我的问题?
  • 如果我理解正确,它只是一个属性文件,当你放置一个观察服务时,任何被更改的文件都会被通知给服务,我相信这就是你想要的。
  • 你有没有读过这个问题??你看标题了吗??我引用自己的话:“我的问题是我有一些包含缓存数据的 bean,我不想丢失这些数据”。您的回答如何帮助解决我的问题?
  • 你认为,重新加载应用程序上下文会保存缓存的数据????无论如何,我认为在这里帮助是犯罪
  • 不,我没有。你仍然不明白我,但我们不是在谈论我,我们在谈论你的答案——你能说出它是如何解决我的问题的吗?下次请不要用不相关的答案浪费人们的时间。祝你有美好的一天
猜你喜欢
  • 1970-01-01
  • 2012-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多