使用ReloadableResourceBundleMessageSource在类路径上动态加载文件

我是Spring的新手,我正在尝试使用它的ReloadableResourceBundleMessageSource类。

我正在尝试使用它,以便我们不再需要重新启动我们的Web应用程序以进行属性文件更改/更新。

我有一个Web应用程序(主要使用JSF)和一个单独的tar组件,其中包含我的所有属性文件。

属性tar的结构如下:

- CompanyOneMessages.properties - CompanyOneMessages_fr_FR.properties - CompanyTwoMessages.properties - CompanyTwoMessages_fr_FR.properties - CompanyThreeMessages.properties - CompanyThreeMessages_fr_FR.properties - ... 

此tar解压缩并部署到服务器上的某个位置,该位置指定为在websphere配置中的类路径上。

我在applicationContext-config.xml中添加了以下内容:

     classpath:com/resource/dynamic/CompanyOneMessages classpath:com/resource/dynamic/CompanyTwoMessages classpath:com/resource/dynamic/CompanyThreeMessages         

一切正常。

但是,它没有完全解决原始问题。 每当我想在我们的应用程序中添加新公司时,我都必须在applicationContext-config.xml文件中添加一个新行并重新部署/重新启动Web应用程序。

我希望能够简单地将新公司属性文件放入属性tar中,并将其动态选取。

是否可以扩展ReloadableResourceBundleMessageSource类,以便在应用程序启动时搜索类路径以查找属性文件并动态加载所有这些类?

更新

这是我到目前为止:

的applicationContext-config.xml文件:

   

MyAPPReloadableResourceBundleMessageSource:

 package com.myapp.resource; import org.springframework.context.support.ReloadableResourceBundleMessageSource; public class MyAPPReloadableResourceBundleMessageSource extends ReloadableResourceBundleMessageSource { public MyAPPReloadableResourceBundleMessageSource() { getResourceBundlesMessages(); // Simply single basename test setBasename("classpath:/resource/dynamic/companyOneMessages"); } @Override public void setBasename(String baesname) { System.out.println("In setBasename"); super.setBasename(baesname); } @Override public void setBasenames(String[] baesnames) { System.out.println("In setBasenames"); super.setBasenames(baesnames); } private String[] getResourceBundlesMessages() { String[] propertiesFiles = null; // How do I get all filenames with .properties under com.resources.dynamic? (location is under classpath) return propertiesFiles; } } 

所以我需要的是如何使用.properties扩展名获取类路径下所有文件的列表?

谢谢

托马斯

ReloadableResourceBundleMessageSource要求文件位于webapp /目录下,而不是在类路径中(它不能重新加载)。

您正在扩展ReloadableResourceBundleMessageSource的正确途径。 正如@JamesC所提到的,以及根据Spring的ReloadableResourceBundleMessageSource的API文档:

由于应用程序服务器通常会缓存从类路径加载的所有文件,因此有必要将资源存储在其他位置(例如,在Web应用程序的“WEB-INF”目录中)。

我和你有类似的要求。 解决它的关键是扩展ReloadableResourceBundleMessageSource并覆盖calculateAllFilenames(String basename, Locale locale)方法,而不仅仅是将语言代码附加到基本名称。

例如,如果我在/srv/myapp/messages下有所有外部消息属性文件(在文件系统中,不是类路径),则重写的方法将执行以下操作:

 @Override protected List calculateAllFilenames(final String basename, final Locale locale) { return super.calculateAllFilenames("file:///srv/myapp/messages/" + basename, locale); } 

在我的例子中,我的basenames列表是静态的,因此,我没有必要覆盖为每个基本名称调用calculateAllFilenames()其他方法。

在您的特定情况下,我将使用Company作为基本名称并覆盖calculateAllFilenames()以扫描类路径之外的目录以解析实际的基本名称,然后为每个已解析的基本名称调用super.calculateAllFilenames() (即super.calculateAllFilenames("file:///path/to/CompanyOneMessages", locale) )。 潜在地,类似于https://stackoverflow.com/a/11223178/1034436的东西会有所帮助。 注意:与引用的答案不同,如果已解析的基本名称列表可以动态更改,我不会将目录扫描作为属性设置器的一部分。 当然,还需要权衡您的应用程序的性能因素,因为它显然会大大增加文件系统访问。