Usando vários arquivos de propriedade (via PropertyPlaceholderConfigurer) em vários projetos / módulos


104

No momento, estamos escrevendo um aplicativo que está dividido em vários projetos / módulos. Por exemplo, vamos pegar os seguintes módulos:

  • myApp-DAO
  • myApp-jabber

Cada módulo tem seu próprio arquivo xml de contexto Spring. Para o módulo DAO, tenho um PropertyPlaceholderConfigurer que lê um arquivo de propriedades com os parâmetros de conexão do banco de dados necessários. No módulo jabber, também tenho um PropertyPlaceHolderConfigurer para as propriedades de conexão do jabber.

Agora vem o aplicativo principal que inclui myApp-DAO e myApp-jabber. Ele lê todos os arquivos de contexto e inicia um grande contexto Spring. Infelizmente, parece que só pode haver um PropertyPlaceholderConfigurer por contexto, portanto, o módulo que for carregado primeiro será capaz de ler seus parâmetros de conexão. O outro lança uma exceção com um erro como "Não foi possível resolver o marcador de posição 'jabber.host'"

Eu meio que entendo qual é o problema, mas não sei realmente uma solução - ou a melhor prática para meu caso de uso.

Como eu configuraria cada módulo para que cada um pudesse carregar seu próprio arquivo de propriedades? No momento, movi PropertyPlaceHolderConfigurer dos arquivos de contexto separados e os mesclei no contexto do aplicativo principal (carregando todos os arquivos de propriedade com um único PropertyPlaceHolderConfigurer). No entanto, isso é uma merda, porque agora todos que usam o módulo dao precisam saber que precisam de um PropertyPlaceHolderConfigurer em seu contexto .. também os testes de integração no módulo dao falham etc.

Estou curioso para saber sobre soluções / ideias da comunidade stackoverflow.

Respostas:


182

Se você garantir que cada espaço reservado, em cada um dos contextos envolvidos, está ignorando as chaves insolúveis, então ambas as abordagens funcionam. Por exemplo:

<context:property-placeholder
location="classpath:dao.properties,
          classpath:services.properties,
          classpath:user.properties"
ignore-unresolvable="true"/>

ou

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

11
Aqui está uma entrada útil sobre o assunto que deve ajudá-lo a resolver ainda mais esses problemas: tarlogonjava.blogspot.com/2009/02/tips-regarding-springs.html
Tim Hennekey

2
OBRIGADO!! ignore-unresolvable = "true" era exatamente o que eu precisava e funcionou!
black666

1
Se você adicionar todos os arquivos em 1 tag, não haverá necessidade de evento ignore-unresolvable="true", caso contrário, será necessário.
Eric Wang

Você pode explicar o significado de ignoreUnresolvablePlaceholders? O que são marcadores de posição não resolvíveis?
emeraldhieu

PropertySourcesPlaceholderConfigureré a implementação de suporte padrão desde Spring 3.1, portanto, é sensato usar em vez de PropertyPlaceholderConfigurercomo a classe de implementação do bean.
jihor

18

Eu sei que essa é uma pergunta antiga, mas o ignore-unresolvableimóvel não estava funcionando para mim e eu não sabia por quê.

O problema era que eu precisava de um recurso externo (algo como location="file:${CATALINA_HOME}/conf/db-override.properties") e o ignore-unresolvable="true"não faz o trabalho neste caso.

O que se precisa fazer para ignorar um recurso externo ausente é:

ignore-resource-not-found="true"

Apenas no caso de alguém esbarrar nisso.


3
ignore-unresolvablee ignore-resource-not-foundservem a propósitos diferentes. Para evitar erros quando o arquivo de propriedades não existe, use ignore-resource-not-found="true". Para evitar erros ao usar uma propriedade que não existe no arquivo , use ignore-unresolvable="true". Se você tiver vários arquivos, cada um contendo conjuntos parciais de propriedades, e cada arquivo pode ou não existir, você precisará usar ambos.
datguy

8

Você pode ter vários <context:property-placeholder />elementos em vez de declarar explicitamente vários beans PropertiesPlaceholderConfigurer.


Tentei usar dois elementos <context: property-placeholder /> e spring reclamou que não conseguiu identificar a propriedade especificada. Tenho que implementar a resposta aceita para que funcione.
Mushy


2

Tentei a solução abaixo, funciona na minha máquina.

<context:property-placeholder location="classpath*:connection.properties" ignore-unresolvable="true" order="1" />

<context:property-placeholder location="classpath*:general.properties" order="2"/>

No caso de vários elementos estarem presentes no contexto Spring, existem algumas práticas recomendadas que devem ser seguidas:

o atributo order precisa ser especificado para corrigir a ordem em que são processados ​​pelo Spring todos os marcadores de posição de propriedade menos o último (ordem mais alta) devem ignore-unresolvable=”true”permitir que o mecanismo de resolução passe para outros no contexto sem lançar uma exceção

fonte: http://www.baeldung.com/2012/02/06/properties-with-spring/


O pedido especificado é obrigatório? Tentei fazer isso e o jvm reclamou.
Mushy
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.