Verwenden mehrerer Eigenschaftendateien (über PropertyPlaceholderConfigurer) in mehreren Projekten / Modulen

104

Wir schreiben derzeit eine Anwendung, die in mehrere Projekte / Module aufgeteilt ist. Nehmen wir zum Beispiel die folgenden Module:

  • myApp-DAO
  • myApp-jabber

Jedes Modul hat eine eigene Spring-Kontext-XML-Datei. Für das DAO-Modul habe ich einen PropertyPlaceholderConfigurer, der eine Eigenschaftendatei mit den erforderlichen Datenbankverbindungsparametern liest. Im Jabber-Modul habe ich auch einen PropertyPlaceHolderConfigurer für die Jabber-Verbindungseigenschaften.

Jetzt kommt die Hauptanwendung, die myApp-DAO und myApp-jabber enthält. Es liest alle Kontextdateien und startet einen großen Spring-Kontext. Leider scheint es nur einen PropertyPlaceholderConfigurer pro Kontext zu geben, sodass jedes Modul, das zuerst geladen wird, seine Verbindungsparameter lesen kann. Der andere löst eine Ausnahme mit dem Fehler "Platzhalter 'jabber.host' konnte nicht aufgelöst werden" aus.

Ich verstehe irgendwie, was das Problem ist, aber ich kenne keine Lösung - oder die beste Vorgehensweise für meinen Anwendungsfall.

Wie würde ich jedes Modul so konfigurieren, dass jedes seine eigene Eigenschaftendatei laden kann? Im Moment habe ich den PropertyPlaceHolderConfigurer aus den separaten Kontextdateien verschoben und sie in den Kontext der Hauptanwendung eingefügt (Laden aller Eigenschaftendateien mit einem einzigen PropertyPlaceHolderConfigurer). Dies ist jedoch zum Kotzen, da jetzt jeder, der das Dao-Modul verwendet, wissen muss, dass er in seinem Kontext einen PropertyPlaceHolderConfigurer benötigt. Auch die Integrationstests im Dao-Modul schlagen fehl usw.

Ich bin gespannt auf Lösungen / Ideen aus der Stackoverflow-Community.

schwarz666
quelle

Antworten:

182

Wenn Sie sicherstellen, dass jeder Platzhalter in jedem der beteiligten Kontexte unlösbare Schlüssel ignoriert, funktionieren beide Ansätze. Beispielsweise:

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

oder

    <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
quelle
11
Hier ist ein nützlicher Eintrag zu diesem Thema, der Ihnen bei der weiteren Lösung dieser Probleme helfen soll: tarlogonjava.blogspot.com/2009/02/tips-regarding-springs.html
Tim Hennekey
2
DANKE!! ignore-unresolvable = "true" war genau das, was ich brauchte und es hat den Trick gemacht!
black666
1
Wenn Sie alle Dateien in einem Tag hinzufügen, brauchen Sie kein Ereignis ignore-unresolvable="true", sonst brauchen Sie.
Eric Wang
Können Sie die Bedeutung von erklären ignoreUnresolvablePlaceholders? Was sind unlösbare Platzhalter?
Smaragdhieu
PropertySourcesPlaceholderConfigurerist die Standard-Backing-Implementierung seit Spring 3.1, daher ist es sinnvoll, sie anstelle PropertyPlaceholderConfigurerder Bean-Implementierungsklasse zu verwenden.
Jihor
18

Ich weiß, dass dies eine alte Frage ist, aber die ignore-unresolvableImmobilie funktionierte nicht für mich und ich wusste nicht warum.

Das Problem war, dass ich eine externe Ressource (so etwas wie location="file:${CATALINA_HOME}/conf/db-override.properties") brauchte und ignore-unresolvable="true"diese in diesem Fall nicht funktioniert.

Was man tun muss, um eine fehlende externe Ressource zu ignorieren, ist:

ignore-resource-not-found="true"

Nur für den Fall, dass jemand anderes darauf stößt.

Raul Rene
quelle
3
ignore-unresolvableund ignore-resource-not-founddienen verschiedenen Zwecken. Um Fehler zu vermeiden , wenn die Eigenschaft Datei nicht existiert, verwendet ignore-resource-not-found="true". Verwenden Sie, um Fehler zu vermeiden, wenn Sie eine Eigenschaft verwenden, die in der Datei nicht vorhanden ist ignore-unresolvable="true". Wenn Sie mehrere Dateien haben, die jeweils teilweise Eigenschaftensätze enthalten, und jede Datei möglicherweise vorhanden ist oder nicht, müssen Sie beide verwenden.
Datum
8

Sie können mehrere <context:property-placeholder />Elemente verwenden, anstatt mehrere PropertiesPlaceholderConfigurer-Beans explizit zu deklarieren.

Earldouglas
quelle
Ich habe versucht, zwei <context: property-placeholder /> -Elemente zu verwenden, und Spring hat sich beschwert, dass die angegebene Eigenschaft nicht identifiziert werden konnte. Ich muss die akzeptierte Antwort implementieren, damit es funktioniert.
Mushy
4

Die PropertiesPlaceholderConfigurerBean hat eine alternative Eigenschaft namens "propertiesArray". Verwenden Sie diese Eigenschaft anstelle der Eigenschaft "properties" und konfigurieren Sie sie mit einer <array>der Eigenschaftsreferenzen.

Stephen C.
quelle
2

Ich habe die folgende Lösung ausprobiert, sie funktioniert auf meinem Computer.

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

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

Wenn im Spring-Kontext mehrere Elemente vorhanden sind, sollten einige bewährte Methoden befolgt werden:

Das order-Attribut muss angegeben werden, um die Reihenfolge festzulegen, in der diese von Spring verarbeitet werden. Alle Eigenschaftsplatzhalter abzüglich des letzten (höchste Reihenfolge) sollten es ignore-unresolvable=”true”ermöglichen, dass der Auflösungsmechanismus im Kontext an andere weitergegeben wird, ohne eine Ausnahme auszulösen

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

onurbaysan
quelle
Ist die angegebene Bestellung erforderlich? Ich habe es versucht und der JVM hat sich beschwert.
Mushy