2011-01-16 14 views
1

für meine Feder-MVC-Anwendung Ich habe mehrere Arten der Konfiguration (Komponententest, Integration, qa, Produktion) erstellt. Alle Konfigurationen befinden sich in einer War-Datei, daher gibt es nur einen Anwendungstyp, den ich erstelle. Welche Konfiguration zu treffen ist, sollte vom Server entschieden werden, auf dem die Anwendung läuft.Spring MVC mit verschiedenen Konfigurationen

Um zu entscheiden, welche Art von Konfiguration verwendet werden soll, muss ich in eine Datei schauen. Danach kann ich entscheiden, welche Konfiguration von spring mvc verwendet werden soll.

Für jetzt per Konvention gibt es immer die -servlet.xml verwendet. Gibt es eine Möglichkeit, dynamisch zu entscheiden, welche Konfiguration zu übernehmen ist?

Grüße, Michael

+0

Es gibt eine geplante Funktion für mehrere Konfigurationen für die nächste Version der Feder. – Bozho

+0

Die allgemeinere Frage dahinter lautet: Wie kann man mit der Konfiguration für mehrere Umgebungen in einer Spring-Anwendung umgehen? –

Antwort

4

Hier ist eine Lösung, die ich benutze. Es funktioniert sehr gut:

  • Legen Sie die Konfigurationsunterschiede in Eigenschaftendateien.
  • Behalten Sie ein einzelnes Spring-XML mit Platzhaltern bei.
  • Verwenden Sie PropertyPlaceholderConfigurer, um die Eigenschaften festzulegen.
  • PropertyPlaceholderConfigurer kann Systemeigenschaften verwenden, um den Namen der zu ladenden Eigenschaftendatei aufzulösen.
  • Legen Sie eine Systemeigenschaft mit dem Namen Ihrer Umgebung fest, bevor Sie PropertyPlaceholderConfigurer initialisieren (Sie können dies in einer Bean tun, die den Wert aus Ihrer Datei liest).

Und los gehts! Die Umgebung wird sauber erkannt und die relevanten Eigenschaften werden geladen!

Keine Notwendigkeit, auf Frühling 3.1 zu warten, können Sie diese Lösung heute mit 3.0 verwenden.

+0

Hallo Axel, danke für deine schnelle Antwort. Soweit ich weiß mit PropertyPlaceholderConfigurer kann nur Eigenschaften konfigurieren. Aber ich möchte auch Beans konfigurieren (inmemory-db statt real-db). – mibutec

+0

Es funktioniert immer noch. Verwenden Sie eine Eigenschaft für den Namen der beanspruchten Bean. Wenn Sie viele Referenzen haben, können Sie einen Alias ​​mit einer Eigenschaft für den Namen der Bean verwenden, auf die er verweist. –

+0

Wenn Sie die Beans als lazy-init = true markieren, werden nur die in der aktuellen Umgebung verwendeten initialisiert. –

0

Ich habe das gleiche Setup, aber ich benutze Maven, um die WARs anders zu bauen. Ich benutze einen PropertyPlaceholderConfigurer im Kontext:

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:p="http://www.springframework.org/schema/p" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 

    <context:property-placeholder location="classpath:datasource.properties" ignore-unresolvable="true" /> 

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" 
     p:driverClassName="${jdbc.driver}" 
     p:url="${jdbc.url}" 
     p:username="${jdbc.username}" 
     p:password="${jdbc.password}" /> 

    <!--other beans--> 
</beans> 

dann ich Setup ein Umgebungen Ordner:

src 
--main 
----environments 
------dev 
--------datasource.properties 
------cert 
--------datasource.properties 
------prod 
--------datasource.properties 

Da ist in meinem Maven pom, ich ein Build-Profil verwenden, alles in der Umgebung Ordner kopieren basiert auf einem System Parameter-flag im maven Befehl:

<profiles> 
     <profile> 
      <id>environment</id> 
      <activation> 
       <property> 
        <name>environment</name> 
       </property> 
      </activation> 
      <build> 
       <resources> 
        <resource> 
         <directory> 
          src/main/environments/${environment} 
         </directory> 
        </resource> 
       </resources> 
       <!-- other build config and plugins --> 

so den folgenden Befehl ein:

mvn clean -Denvironment=dev install 

würden die Entwickler datasource.properties den Krieg kopieren

+0

Das war mein erster Plan. Aber ich werde meine Anwendung in einem VM-Image speichern und dieses Image auf meinen Servern bereitstellen. Also brauche ich meine Anwendung als jede Art von Instanz zu arbeiten – mibutec

+0

Erstellen eines anderen Artefakts für jede Umgebung ist ein wenig böse - siehe meine Antwort hier, um dynamische Laden von Eigenschaften pro env zu ermöglichen: http://stackoverflow.com/questions/1311360/ property-placeholder-location-from-another-property/1312341 # 1312341 – Pablojim

+1

Ich bin mit Pablojim auf diesem. Artefakt/Umgebung ist ein (leider weit verbreitetes) Anti-Pattern. Es untergräbt die Glaubwürdigkeit von Tests, da Sie grundsätzlich ein anderes Artefakt in die Produktion einbringen als das, das Sie getestet haben. –

0

Denn ich bin mit PropertyPlaceholderConfigurer aber etwas unterschiedlich, als Axel erwähnt: Ich habe eine Eigenschaft von meiner Konfiguration zu laden und verwenden Sie es, die Einfuhr zu verwenden, um zu bestimmen. Wegen https://jira.springframework.org/browse/SPR-1332 kann ich nicht eine Datei verwenden, um den Instanztyp zu speichern, aber Umgebungsvariablen verwenden.

<bean id="propertyConfigurerOne" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/> 
<import resource="classpath:/web${vabse.Environment}.xml"/> 
+0

Dies ist sicherlich ein gültiger Weg (und viel besser als die weit verbreitete Artefakt/Umgebung Anti-Muster). Wie ich in meiner Antwort beschrieben habe, können Sie immer noch eine Datei verwenden, wenn Sie ihren Wert in eine Systemeigenschaft einlesen. (Ich verwende diese genaue Lösung mit meinem aktuellen Client) –

+0

Der Grund, warum ich den Property-Ansatz bevorzuge, anstatt den Import, den Sie hier haben, ist, dass ich sicherstellen möchte, dass die Verkabelung meiner Beans in allen Umgebungen so ähnlich wie möglich ist um die Wirksamkeit von Tests zu erhöhen und Überraschungen in der Produktion zu vermeiden. –