Динамически загружать файлы в путь к классам, используя ReloadableResourceBundleMessageSource - PullRequest
4 голосов
/ 27 января 2012

Я новичок в Spring и пытаюсь использовать его класс ReloadableResourceBundleMessageSource.

Я пытаюсь использовать его, чтобы нам больше не приходилось перезапускать наше веб-приложение для изменений / обновлений файлов свойств.

У меня есть веб-приложение (в основном использующее JSF) и отдельный компонент tar, который содержит все мои файлы свойств.

Структура свойств смолы выглядит следующим образом:

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

Этот tar распаковывается и развертывается в местоположении на сервере, которое указано как путь к классам в конфигурациях websphere.

Я добавил следующее в свое applicationContext-config.xml:

<!-- Enable reloading of resource bundles without requiring web-app restart -->
    <bean id="messages"
        class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basenames">
            <list>  
                <value>classpath:com/resource/dynamic/CompanyOneMessages</value>
                <value>classpath:com/resource/dynamic/CompanyTwoMessages</value>
                <value>classpath:com/resource/dynamic/CompanyThreeMessages</value>              
            </list>
        </property>     
        <property name="cacheSeconds" value="1" />
    </bean>

    <!-- Declare location of bean to handle messages and define property reference 
         we will use to reference message properties throughout the presentation layer -->
    <bean id="myappMessages" class="com.myapp.resource.MyAPPMessages">
        <property name="messages" ref="messages" />
    </bean>

Это все отлично работает.

НО, это не полностью решает исходную проблему. Каждый раз, когда я хочу добавить новую компанию в наше приложение, мне нужно будет добавить новую строку в файл applicationContext-config.xml и повторно развернуть / перезапустить веб-приложение.

Я хотел бы иметь возможность просто перенести новый файл свойств компании в tar свойств и получить его динамическое получение.

Можно ли расширить класс ReloadableResourceBundleMessageSource таким образом, чтобы при запуске приложения он искал путь к классам для файлов свойств и динамически загружал их все?

Обновление

Это то, что я имею до сих пор:

ApplicationContext-config.xml:

<bean id="messages" class="com.resource.MyAPPReloadableResourceBundleMessageSource">
</bean>

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;
    }
}

Итак, все, что мне нужно, это как получить список всех файлов в classpath с расширением .properties?

Спасибо

Thomas

Ответы [ 2 ]

4 голосов
/ 22 августа 2012

ReloadableResourceBundleMessageSource требует, чтобы файлы находились в каталоге webapp / /, а не в вашем пути к классам (он не может их перезагрузить).

2 голосов
/ 29 сентября 2014

Вы находитесь на правильном пути расширения ReloadableResourceBundleMessageSource.Как упоминалось в @JamesC, и в соответствии с документацией API Spring для ReloadableResourceBundleMessageSource:

Поскольку серверы приложений обычно кэшируют все файлы, загруженные из пути к классам, необходимо хранить ресурсы где-нибудь еще (например, вКаталог веб-приложения "WEB-INF".

У меня было такое же требование, как и у вас.Клавиша для ее решения расширяет ReloadableResourceBundleMessageSource и переопределяет метод calculateAllFilenames(String basename, Locale locale), чтобы сделать больше, чем просто добавление кодов языков к базовому имени.

Например, если у меня есть все мои внешние файлы свойств сообщения в /srv/myapp/messages (в файловой системе, НЕ в classpath), переопределенный метод будет выглядеть примерно так:

@Override
protected List<String> calculateAllFilenames(final String basename,
        final Locale locale) {

   return super.calculateAllFilenames("file:///srv/myapp/messages/" + basename, 
           locale);
}

В моемВ этом случае мой список basenames является статическим и, следовательно, мне не пришлось переопределять другие методы, которые вызывают calculateAllFilenames() для каждого базового имени.

В вашем конкретном случае я бы использовал Company в качествебазовое имя и переопределение calculateAllFilenames() для сканирования каталога за пределами вашего classpath для разрешения фактических базовых имен, а затем вызовите super.calculateAllFilenames() для каждого разрешенного базового имени (то есть super.calculateAllFilenames("file:///path/to/CompanyOneMessages", locale)).Потенциально может помочь что-то похожее на https://stackoverflow.com/a/11223178/1034436.Примечание: в отличие от ссылочного ответа, я не буду выполнять сканирование каталогов как часть установщика свойств, если разрешенный список базовых имен может изменяться динамически.Конечно, необходимо учитывать и соображения производительности вашего приложения, поскольку это, очевидно, значительно увеличит доступ к файловой системе.

...