Utilisation de plusieurs fichiers de propriétés (via PropertyPlaceholderConfigurer) dans plusieurs projets / modules

104

Nous écrivons actuellement une application qui est divisée en plusieurs projets / modules. Par exemple, prenons les modules suivants:

  • myApp-DAO
  • myApp-jabber

Chaque module a son propre fichier xml de contexte Spring. Pour le module DAO, j'ai un PropertyPlaceholderConfigurer qui lit un fichier de propriétés avec les paramètres de connexion de base de données nécessaires. Dans le module jabber, j'ai également un PropertyPlaceHolderConfigurer pour les propriétés de connexion jabber.

Vient maintenant l'application principale qui comprend myApp-DAO et myApp-jabber. Il lit tous les fichiers de contexte et démarre un gros contexte Spring. Malheureusement, il semble qu'il ne puisse y avoir qu'un seul PropertyPlaceholderConfigurer par contexte, donc le module chargé en premier est capable de lire ses paramètres de connexion. L'autre lève une exception avec une erreur telle que "Impossible de résoudre l'espace réservé 'jabber.host'"

Je comprends en quelque sorte quel est le problème, mais je ne connais pas vraiment de solution - ni la meilleure pratique pour mon cas d'utilisation.

Comment configurer chaque module pour que chacun puisse charger son propre fichier de propriétés? En ce moment, j'ai déplacé le PropertyPlaceHolderConfigurer hors des fichiers de contexte séparés et les ai fusionnés dans le contexte de l'application principale (chargement de tous les fichiers de propriétés avec un seul PropertyPlaceHolderConfigurer). Cela craint, car maintenant, tous ceux qui utilisent le module dao doivent savoir qu'ils ont besoin d'un PropertyPlaceHolderConfigurer dans leur contexte ... les tests d'intégration dans le module dao échouent, etc.

Je suis curieux de connaître les solutions / idées de la communauté stackoverflow.

noir666
la source

Réponses:

182

Si vous vous assurez que chaque espace réservé, dans chacun des contextes impliqués, ignore les clés insolubles, ces deux approches fonctionnent. Par exemple:

<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>
Tim Hennekey
la source
11
Voici une entrée utile sur le sujet qui devrait vous aider à résoudre ces problèmes: tarlogonjava.blogspot.com/2009/02/tips-regarding-springs.html
Tim Hennekey
2
MERCI!! ignore-unresolvable = "true" était exactement ce dont j'avais besoin et ça a fait l'affaire!
black666
1
Si vous ajoutez tous les fichiers dans 1 balise, alors aucun événement n'est nécessaire ignore-unresolvable="true", sinon besoin.
Eric Wang
Pouvez-vous expliquer la signification de ignoreUnresolvablePlaceholders? Que sont les espaces réservés insolubles?
emeraldhieu
PropertySourcesPlaceholderConfigurerest l'implémentation de support par défaut depuis Spring 3.1, il est donc judicieux de l'utiliser à la place de PropertyPlaceholderConfigurercomme classe d'implémentation du bean.
jihor
18

Je sais que c'est une vieille question, mais la ignore-unresolvablepropriété ne fonctionnait pas pour moi et je ne savais pas pourquoi.

Le problème était que j'avais besoin d'une ressource externe (quelque chose comme location="file:${CATALINA_HOME}/conf/db-override.properties") et le ignore-unresolvable="true"ne fait pas le travail dans ce cas.

Ce qu'il faut faire pour ignorer une ressource externe manquante est:

ignore-resource-not-found="true"

Juste au cas où quelqu'un d'autre se heurterait à ça.

Raul René
la source
3
ignore-unresolvableet ignore-resource-not-foundservent à des fins différentes. Pour éviter les erreurs lorsque le fichier de propriétés n'existe pas, utilisez ignore-resource-not-found="true". Pour éviter les erreurs lorsque vous utilisez une propriété qui n'existe pas dans le fichier , utilisez ignore-unresolvable="true". Si vous avez plusieurs fichiers contenant chacun des ensembles partiels de propriétés et que chaque fichier peut exister ou non, vous devrez utiliser les deux.
datguy
8

Vous pouvez avoir plusieurs <context:property-placeholder />éléments au lieu de déclarer explicitement plusieurs beans PropertiesPlaceholderConfigurer.

Earldouglas
la source
J'ai essayé d'utiliser deux éléments <context: property-placeholder /> et spring s'est plaint de ne pas pouvoir identifier la propriété spécifiée. Je dois mettre en œuvre la réponse acceptée pour que cela fonctionne.
Mushy le
4

Le PropertiesPlaceholderConfigurerbean a une propriété alternative appelée "propertiesArray". Utilisez-la à la place de la propriété "properties" et configurez-la avec une <array>référence de propriété.

Stephen C
la source
2

J'ai essayé la solution ci-dessous, cela fonctionne sur ma machine.

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

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

Si plusieurs éléments sont présents dans le contexte Spring, il existe quelques bonnes pratiques à suivre:

l'attribut order doit être spécifié pour fixer l'ordre dans lequel ceux-ci sont traités par Spring, tous les espaces réservés de propriété moins le dernier (ordre le plus élevé) devraient avoir ignore-unresolvable=”true”pour permettre au mécanisme de résolution de passer à d'autres dans le contexte sans lever d'exception

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

onurbaysan
la source
La commande spécifiée est-elle requise? J'ai essayé cela et le jvm s'est plaint.
Mushy le