Profilo predefinito in primavera 3.1


100

Nella mia applicazione ho i bean annotati con @Profile("prod")e @Profile("demo"). Il primo, come puoi intuire :), è usato sui bean che si connettono al DB di produzione e il secondo annota i bean che usano qualche falso DB ( HashMapo qualsiasi altra cosa) - per rendere lo sviluppo più veloce.

Quello che vorrei avere è il profilo predefinito ( "prod") che verrà usato sempre se non è sovrascritto da " qualcos'altro ".

Perfetto sarebbe avere nel mio web.xml:

<context-param>
     <param-name>spring.profiles.active</param-name>
     <param-value>prod</param-value>
</context-param>

e quindi sovrascrivi questo con in -Dspring.profiles.active="demo"modo che io possa fare:

mvn jetty:run -Dspring.profiles.active="demo". 

Ma purtroppo questo non funziona. Qualche idea su come potrei ottenerlo? L'impostazione -Dspring.profiles.active="prod"su tutti i miei ambienti non è un'opzione.

Risposte:


67

La mia esperienza è che usando

@Profile("default")

il bean verrà aggiunto al contesto solo se non viene identificato nessun altro profilo. Se si passa a un profilo diverso, ad esempio -Dspring.profiles.active="demo", questo profilo viene ignorato.


4
La risposta accettata dipende da web.xml (e va bene), ma questa risposta funziona sia che tu abbia web.xml o meno e quindi è più ampiamente utile a tutti.
Jay

1
questa soluzione è molto più pulita
cahen

È una caratteristica ufficiale o un effetto collaterale? Vuoi collegarti alla documentazione di Spring dove viene descritta questa caratteristica?
rustyx

111

Definisci il tuo ambiente di produzione come profilo predefinito nel tuo web.xml

<context-param>
   <param-name>spring.profiles.default</param-name>
   <param-value>prod</param-value>
</context-param>

e se vuoi usare un profilo diverso passalo come proprietà di sistema

mvn -Dspring.profiles.active="demo" jetty:run

3
No, ha cercato di definire il profilo attivo nel web.xml e come proprietà di sistema. Nella mia soluzione configuro un profilo predefinito nel web.xml e sovrascrivo / definisco il profilo attivo tramite la proprietà di sistema. Se non è presente un profilo attivo esplicito, verrà utilizzato il valore predefinito.
andih

1
Grazie! questo è esattamente quello che volevo! non riuscivo a trovarlo da nessuna parte: /
Michał Margiel

Un problema con questo approccio: se si imposta spring.profiles.default=prodin application.properties, quindi application-prod.propertiesnon verrà caricato. Questo è controintuitivo.
gamliela

@gamliela L'approccio non imposta il profilo predefinito in un application.propertiesfile. Per sapere che application-prod.propertiesdovrebbe essere utilizzato devi conoscere il profilo. Questo è ciò che fa questo approccio. Definisce i profili al di fuori del contesto della molla web.xml(predefinita) o tramite la variabile di ambiente (sovrascrive l'impostazione predefinita).
andih

@andih Sì, lo so, ma dico solo che non è intuitivo e quindi problematico. Da quando application-default.propertiesvengo caricato, mi aspetto che application-newdefault.propertiesvenga caricato anche quello. Non è un problema con la tua soluzione, è un problema con la primavera ...
gamliela

6

Ho lo stesso problema, ma utilizzo WebApplicationInitializer per configurare ServletContext a livello di programmazione (Servlet 3.0+). Quindi faccio quanto segue:

public class WebAppInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext sc) throws ServletException {
        // Create the 'root' Spring application context
        final AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        // Default active profiles can be overridden by the environment variable 'SPRING_PROFILES_ACTIVE'
        rootContext.getEnvironment().setDefaultProfiles("prod");
        rootContext.register(AppConfig.class);

        // Manage the lifecycle of the root application context
        sc.addListener(new ContextLoaderListener(rootContext));
    }
}

5

Puoi anche considerare di rimuovere il profilo PROD e utilizzare @Profile ("! Demo")


2
Suppongo che questo non funzionerebbe nel caso tu abbia più di due profili, giusto?
Chop

3

Informazioni sull'impostazione del profilo di produzione predefinito già pubblicato su @andih

Il modo più semplice per impostare il profilo predefinito per il plug-in Maven Jetty è includere l'elemento seguente nella configurazione del plug-in:

<plugin>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-maven-plugin</artifactId>
    <configuration>
        <systemProperties>
            <systemProperty>
                <name>spring.profiles.active</name>
                <value>demo</value>
            </systemProperty>
        </systemProperties>
    </configuration>
</plugin>

3

La molla fornisce due proprietà separate quando si determina quali profili sono attivi:

  • spring.profiles.active

e

  • spring.profiles.default

Se spring.profiles.activeè impostato, il suo valore determina quali profili sono attivi. Ma se spring.profiles.activenon è impostato, allora la primavera sembraspring.profiles.default.

Se né spring.profiles.activespring.profiles.defaultè impostato, non ci sono profili attivi e vengono creati solo quei bean che non sono definiti come appartenenti a un profilo. Qualsiasi bean che non specifica un profilo appartiene al defaultprofilo.


-1

Puoi configurare il tuo web.xml come risorsa filtrata e fare in modo che questo valore venga riempito da maven dalle impostazioni del profilo maven: questo è quello che facciamo.

in pom filtra tutte le risorse (puoi farlo se non hai il segno $ {} in esse)

<webResources>
    <resource>
        <directory>src/main/webapp</directory>
        <filtering>true</filtering>
    </resource>
</webResources>

in web.xml inserire

<context-param>
     <param-name>spring.profiles.active</param-name>
     <param-value>${spring.prfile}</param-value>
</context-param>

in pom creare profili maven

<profiles>
    <profile>
        <id>DEFAULT</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <spring.profile>prod</spring.profile>
        </properties>
    <profile>
    <profile>
        <id>DEMO</id>
        <properties>
            <spring.profile>demo</spring.profile>
        </properties>
    <profile>
</profiles>

Ora puoi usare

mvn jetty:run -P DEMO

o semplicemente -P DEMOcon qualsiasi comando esperto


1
Non ne sono sicuro, ma penso che non funzionerà. Pontile IMHO: l'esecuzione non verrà eseguita nella fase in cui le risorse vengono filtrate.
Michał Margiel

Ovviamente è necessario eseguire mvn clean compile jetty: eseguire -P DEMO, ma con codice non compilato lo esegue automaticamente
Hurda

10
Capisco che uno degli obiettivi principali dei profili Spring 3.1 è generare un singolo file WAR pronto per essere distribuito in tutti gli ambienti. L'utilizzo dei profili Maven è un passo indietro allo stato precedente: dove era necessario il packaging di un file WAR per ogni ambiente ...
edrabc

@edrabc stava chiedendo mvn jetty: run - non c'è nessun file WAR.
Hurda

D'accordo @Hurda. Ma stava anche chiedendo di eseguire il comando in più ambienti: avere un mix di profili Maven e profili Spring potrebbe essere un po 'fuorviante ...
edrabc
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.