Подтвердить что ты не робот

Импортировать файл конфигурации Spring на основе свойства в файле .properties.

В моей конфигурации Spring xml я пытаюсь заставить что-то вроде этого работать:

<beans>

   <import resource="${file.to.import}" />

   <!-- Other bean definitions -->

</beans>

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

Примечание. Свойство PropertyPlaceHolderConfigurer не будет работать. Импорт разрешается до запуска любых BeanFactoryPostProcessors. Элемент import может разрешать только System.properties.

У кого-нибудь есть простое решение? Я не хочу запускать классы классов подкласса и т.д....

Спасибо

4b9b3361

Ответ 1

Это, к сожалению, намного сложнее, чем должно быть. В моем приложении я выполнил это, выполнив следующие действия:

  • Небольшой контекст "bootstrap", который отвечает за загрузку PropertyPlaceholderConfigurer bean и еще один bean, который отвечает за загрузку контекста приложения.

  • Второй bean, упомянутый выше, принимает в качестве входных данных "реальные" spring файлы контекста для загрузки. У меня есть файлы контекста spring, организованные так, что конфигурируемая часть хорошо известна и находится там же. Например, у меня может быть 3 файла конфигурации: one.onpremise.xml, one.hosted.xml, one.multitenant.xml. bean программно загружает эти файлы контекста в текущий контекст приложения.

Это работает, потому что файлы контекста указаны в качестве входных данных bean, ответственных за их загрузку. Это не сработает, если вы просто попытаетесь сделать импорт, как вы упомянули, но это имеет тот же эффект, что и немного больше. Класс bootstrap выглядит примерно так:

 public class Bootstrapper implements ApplicationContextAware, InitializingBean {

    private WebApplicationContext context;
    private String[] configLocations;
    private String[] testConfigLocations;
    private boolean loadTestConfigurations;

    public void setConfigLocations(final String[] configLocations) {
        this.configLocations = configLocations;
    }

    public void setTestConfigLocations(final String[] testConfigLocations) {
        this.testConfigLocations = testConfigLocations;
    }

    public void setLoadTestConfigurations(final boolean loadTestConfigurations) {
        this.loadTestConfigurations = loadTestConfigurations;
    }

    @Override
    public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException {
        context = (WebApplicationContext) applicationContext;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        String[] configsToLoad = configLocations;

        if (loadTestConfigurations) {
            configsToLoad = new String[configLocations.length + testConfigLocations.length];
            arraycopy(configLocations, 0, configsToLoad, 0, configLocations.length);
            arraycopy(testConfigLocations, 0, configsToLoad, configLocations.length, testConfigLocations.length);
        }

        context.setConfigLocations(configsToLoad);
        context.refresh();
    }
}

В принципе, получите контекст приложения, задайте его местоположения конфигурации и скажите ему, чтобы он обновился. Это отлично работает в моем приложении.

Надеюсь, что это поможет.

Ответ 3

В Spring JIRA есть старая проблема для добавления свойств поддержки заполнитель для импорта (SPR-1358), которая была разрешена как "Не будет исправлять", но с тех пор было предложено решение с использованием EagerPropertyPlaceholderConfigurer.

Я лоббировал возобновление SPR-1358, но ответа пока нет. Возможно, если другие добавят свои варианты использования в комментарии к комментариям, которые помогут повысить осведомленность.

Ответ 4

Почему бы и нет:

  • прочитайте свой файл свойств при запуске
  • который определит, какую конфигурацию Spring загрузить
  • в зависимости от того, что загружается config Spring, устанавливает определенные вещи, затем загружает общий Spring config

чтобы вы эффективно инвертировали свое предлагаемое решение.

Ответ 5

Добавьте что-то похожее на следующее:

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="ignoreResourceNotFound"><value>true</value></property>
    <property name="locations">
        <list>
            <value>classpath:propertyfile.properties</value>
        </list>
    </property>
</bean>

Ответ 6

Если вы хотите указать импортированное имя XML файла вне applicationContext.xml, чтобы вы могли заменить applicationContext.xml, не теряя конфигурацию импортированного пути к файлу XML, вы можете просто добавить промежуточный Spring beans XML файл, скажем, confSelector.xml, так что importContext.xml импортирует confSelector.xml и confSelector.xml только содержит элемент <import> , который ссылается на соответствующий пользовательский XML файл beans.

Другим средством, которое может быть полезно, являются XML-сущности (определенные путем добавления элементов <! ENTITY... > в объявление DTD в начале XML). Они позволяют импортировать XML-фрагменты из других файлов и предоставлять функциональность "заполнитель-заполнитель" для любого XML файла.

Ни одно из этих решений не позволяет вам иметь файл конфигурации в формате Java.properties.

Ответ 7

Ответ Андре Шустера, который я натолкнулся, помог мне решить очень похожую проблему, которую я испытывал, желая найти другое выражение свойств в зависимости от того, работал ли я на своем собственном хосте, Дженкинсом на нашем сборке или в "реального" развертывания. Я сделал это:

<context:property-placeholder location="file:///etc/myplace/database.properties" />

а затем

<bean id="propertyConfigurer"
      class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>WEB-INF/classes/resources/database.properties</value>
            ...
        </list>
    </property>
</bean>

который решил мою проблему, потому что на моем хосте разработки я поместил ссылку на свою собственную базу данных database.properties в /etc/myplace/database.properties и немного другую на сервере Jenkins. В реальном развертывании такой файл не найден, поэтому Spring возвращается в "реальный" в ресурсах в подкаталоге файлов классов. Если указанные свойства уже указаны в файле /etc/myplace/database.properties, то (к счастью) они не переопределяются локальным файлом.

Ответ 8

Другим обходным решением, которое не зависит от свойств системы, является загрузка свойств всех файлов с использованием другого PropertyPlaceholderConfigurer для каждого файла и определение другого placeholderPrefix для каждого из них. Этот placeholderprefix настраивается исходным файлом свойств.



Определите первый файл свойства: (содержащий первый или второй)

global.properties

fileToUse=first


Определите файлы, содержащие свойство, которое может быть переключено в зависимости от свойства, указанного выше:

first.properties

aProperty=propertyContentOfFirst

second.properties

aProperty=propertyContentOfSecond


Затем определите держатели мест для всех файлов:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations">
        <list>
            <value>classpath:global.properties</value>
        </list>
    </property>
</bean>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="placeholderPrefix" value="first{" />
    <property name="locations">
        <list>
            <value>classpath:first.properties</value>
        </list>
    </property>
</bean>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="placeholderPrefix" value="second{" />
    <property name="locations">
        <list>
            <value>classpath:second.properties</value>
        </list>
    </property>
</bean>


Используйте свойство, определенное в глобальном, для определения ресурса для использования из другого файла:

${fileToUse}{aProperty}

Ответ 9

Если я добавлю аргумент JVM ниже и файл myApplicationContext.dev.xml, spring загрузит

-DmyEnvironment = DEV

<context:property-placeholder />

<import resource="classpath:/resources/spring/myApplicationContext.${myEnvironment}.xml"/>

Ответ 10

Я использую Spring 3 и загружаю такие свойства:

<context:property-placeholder location="/WEB-INF/my.properties" />