Profil par défaut dans Spring 3.1

100

Dans mon application, j'ai des beans annotés avec @Profile("prod")et @Profile("demo"). Le premier, comme vous pouvez le deviner :), est utilisé sur les beans qui se connectent à la base de données de production et le second annote les beans qui utilisent une fausse DB ( HashMapou autre) - pour accélérer le développement.

Ce que j'aimerais avoir, c'est le profil par défaut ( "prod") qui sera toujours utilisé s'il n'est pas remplacé par " quelque chose-d'autre ".

Parfait serait d'avoir dans mon web.xml:

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

puis remplacez-le par -Dspring.profiles.active="demo"pour que je puisse faire:

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

Mais malheureusement, cela ne fonctionne pas. Une idée comment pourrais-je y parvenir? La configuration -Dspring.profiles.active="prod"sur tous mes environnements n'est pas une option.

Michał Margiel
la source

Réponses:

67

Mon expérience est que l'utilisation

@Profile("default")

le bean ne sera ajouté au contexte que si aucun autre profil n'est identifié. Si vous passez dans un profil différent, par exemple -Dspring.profiles.active="demo", ce profil est ignoré.

Paul Philion
la source
4
La réponse acceptée dépend de web.xml (et c'est très bien), mais cette réponse fonctionne que vous ayez web.xml ou non et est donc plus largement utile à tout le monde.
Jay
1
cette solution est beaucoup plus propre
cahen
Est-ce une fonctionnalité officielle ou un effet secondaire? Souhaitez-vous créer un lien vers la documentation Spring où cette fonctionnalité est décrite?
rustyx
111

Définissez votre environnement de production comme profil par défaut dans votre web.xml

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

et si vous souhaitez utiliser un profil différent, passez-le comme propriété système

mvn -Dspring.profiles.active="demo" jetty:run
Andih
la source
3
Non, il a essayé de définir le profil actif dans le fichier web.xml et en tant que propriété système. Dans ma solution, je configure un profil par défaut dans le fichier web.xml et écrase / définit le profil actif via la propriété système. S'il n'y a pas de profil actif explicite, la valeur par défaut sera utilisée.
andih
1
Merci! c'est exactement ce que je voulais! je ne l'
ai
Un problème avec cette approche: si vous définissez spring.profiles.default=proddans application.properties, puis application-prod.propertiesne sera pas chargé. C'est contre-intuitif.
gamliela
@gamliela L'approche ne définit pas le profil par défaut dans un application.propertiesfichier. Afin de savoir ce qui application-prod.propertiesdevrait être utilisé, vous devez connaître le profil. C'est ce que fait cette approche. Il définit des profils en dehors du contexte de ressort soit la web.xmlvariable d'environnement (par défaut) ou via (écrase la valeur par défaut).
andih
@andih Oui, je le sais, mais je dis seulement que ce n'est pas intuitif et donc problématique. Depuis le application-default.propertieschargement, je m'attends également à ce que application-newdefault.propertiesce soit également chargé. Ce n'est pas un problème avec votre solution, c'est un problème avec Spring ...
gamliela
6

J'ai le même problème, mais j'utilise WebApplicationInitializer afin de configurer le ServletContext par programme (Servlet 3.0+). Alors je fais ce qui suit:

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));
    }
}
mcoolive
la source
5

Vous pouvez également envisager de supprimer le profil PROD et utiliser @Profile ("! Démo")

Blacelle
la source
2
Je suppose que cela ne fonctionnerait pas au cas où vous auriez plus de deux profils, non?
Chop le
3

À propos de la définition du profil de production par défaut déjà publié @andih

Le moyen le plus simple de définir le profil par défaut pour le plugin maven jetty est d'inclure l'élément ci-dessous dans la configuration de votre plugin:

<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>
Jakub Kubrynski
la source
3

Spring fournit deux propriétés distinctes lors de la détermination des profils actifs:

  • spring.profiles.active

et

  • spring.profiles.default

Si spring.profiles.activeest défini, sa valeur détermine les profils actifs. Mais si ce spring.profiles.activen'est pas réglé, alors le printemps se tourne versspring.profiles.default.

Si ni spring.profiles.activeni spring.profiles.defaultn'est défini, il n'y a pas de profil actif et seuls les beans qui ne sont pas définis comme faisant partie d'un profil sont créés. Tout bean qui ne spécifie pas de profil appartient au defaultprofil.

Touhidur Rahaman Khan
la source
-1

Vous pouvez configurer votre web.xml en tant que ressource filtrée et faire remplir cette valeur par maven à partir des paramètres de profil maven - c'est ce que nous faisons.

dans pom filtre toutes les ressources (vous pouvez le faire si vous n'avez pas de marquage $ {})

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

dans web.xml mettre

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

dans pom créer des profils 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>

Maintenant vous pouvez utiliser

mvn jetty:run -P DEMO

ou simplement -P DEMOavec n'importe quelle commande maven

Hurda
la source
1
Je ne suis pas sûr mais je pense que cela ne fonctionnera pas. Jetée IMHO: run ne fonctionnera pas phase dans laquelle les ressources sont filtrées.
Michał Margiel
de caurse, vous devez exécuter mvn clean compile jetty: exécutez -P DEMO, mais avec du code non compilé, il l'exécute automatiquement
Hurda
10
Je comprends que l'un des principaux objectifs des profils Spring 3.1 est de générer un fichier WAR unique prêt à être déployé dans tous les environnements. L'utilisation des profils Maven est un retour à l'état précédent: où l'empaquetage d'un fichier WAR était nécessaire pour chaque environnement ...
edrabc
@edrabc il demandait mvn jetty: run - il n'y a pas de fichier WAR.
Hurda
D'accord @Hurda. Mais il demandait également d'exécuter la commande dans plusieurs environnements: avoir un mélange de profils Maven et de profils Spring pourrait être un peu trompeur ...
edrabc