Profils de printemps

Profils de printemps

1. Vue d'ensemble

Dans cet article, nous allons nous concentrer sur l'introduction deProfiles in Spring.

Les profils sont une caractéristique principale du framework - nous permettant de mapper nos beans à différents profils - par exemple,dev,test,prod.

Nous pouvons ensuite activer différents profils dans différents environnements pour démarrer uniquement les beans dont nous avons besoin:

Lectures complémentaires:

Configuration de sources de données de ressort distinctes pour les tests

Tutoriel rapide et pratique sur la configuration d'une source de données distincte à tester dans une application Spring.

Read more

Propriétés avec ressort et botte de printemps

Didacticiel sur l'utilisation des fichiers de propriétés et des valeurs de propriétés dans Spring.

Read more

2. Utiliser@Profile sur un Bean

Commençons simplement et voyons comment nous pouvons faire en sorte qu'un bean appartienne à un profil particulier. En utilisant l'annotation@Profile - nous mappons le bean à ce profil particulier; l'annotation prend simplement les noms d'un (ou de plusieurs) profils.

Prenons un scénario de base: nous avons un haricot qui ne devrait être actif que pendant le développement, mais non déployé en production. Nous annotons ce bean avec un profil «dev», et il ne sera présent que dans le conteneur pendant le développement - en production, lesdevne seront tout simplement pas actifs:

@Component
@Profile("dev")
public class DevDatasourceConfig

En résumé, les noms de profil peuvent également être précédés d’un opérateur NOT, par exemple. «!dev» pour les exclure d'un profil.

Dans l'exemple ci-dessous, le composant est activé uniquement si le profil «dev» n'est pas actif:

@Component
@Profile("!dev")
public class DevDatasourceConfig

3. Déclarer des profils en XML

Les profils peuvent également être configurés en XML - la balise<beans> a l'attribut“profiles” qui prend les valeurs séparées par des virgules des profils applicables:


    

4. Définir des profils

L'étape suivante consiste à activer et à définir les profils afin que les beans respectifs soient enregistrés dans le conteneur.

Cela peut être fait de différentes manières - que nous explorerons dans les sections suivantes.

4.1. Programmation via l'interfaceWebApplicationInitializer

Dans les applications Web,WebApplicationInitializer peut être utilisé pour configurer lesServletContext par programmation.

C'est également un emplacement très pratique pour définir nos profils actifs par programmation:

@Configuration
public class MyWebApplicationInitializer
  implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {

        servletContext.setInitParameter(
          "spring.profiles.active", "dev");
    }
}

4.2. Programmation viaConfigurableEnvironment

Vous pouvez également définir des profils directement sur l'environnement:

@Autowired
private ConfigurableEnvironment env;
...
env.setActiveProfiles("someProfile");

4.3. Paramètre de contexte enweb.xml

De même,profiles can be activated in the web.xml de l'application Web également, en utilisant un paramètre de contexte:


    contextConfigLocation
    /WEB-INF/app-config.xml


    spring.profiles.active
    dev

4.4. Paramètre système JVM

Les noms de profil peuvent également être transmis via un paramètre système JVM. Les noms de profil passés en tant que paramètre seront activés lors du démarrage de l'application:

-Dspring.profiles.active=dev

4.5. Variable d'environnement

Dans un environnement Unix,profiles can also be activated via the environment variable:

export spring_profiles_active=dev

4.6. Profil de Maven

Les profils Spring peuvent également être activés via les profils Maven, en spécifiant la propriétéspring.profiles.active configuration.

Dans chaque profil Maven, nous pouvons définir une propriétéspring.profiles.active:


    
        dev
        
            true
        
        
            dev
        
    
    
        prod
        
            prod
        
    

Sa valeur sera utilisée pour remplacer l'espace réservé@[email protected] dansapplication.properties:

[email protected]@

Maintenant, nous devons activer le filtrage des ressources danspom.xml:


    
        
            src/main/resources
            true
        
    
    ...

Et ajoutez un paramètre-P pour changer le profil Maven qui sera appliqué:

mvn clean package -Pprod

Cette commande empaquera l'application pour le profilprod. Il applique également la valeurspring.profiles.active ‘prod' pour cette application lorsqu'elle est en cours d'exécution.

4.7. @ActiveProfile dans les tests

Les tests permettent de spécifier très facilement les profils actifs - en utilisant l'annotation@ActiveProfile pour activer des profils spécifiques:

@ActiveProfiles("dev")

Pour résumer, nous avons examiné plusieurs manières d'activer les profils. Voyons maintenant lequel a la priorité sur l'autre et ce qui se passe si vous en utilisez plusieurs, de la priorité la plus élevée à la plus basse:

  1. Paramètre de contexte enweb.xml

  2. WebApplicationInitializer

  3. Paramètre système JVM

  4. Variable d'environnement

  5. Profil Maven

5. Le profil par défaut

Tout bean qui ne spécifie pas de profil appartient au profil «default».

Spring fournit également un moyen de définir le profil par défaut lorsqu'aucun autre profil n'est actif - en utilisant la propriété «spring.profiles.default».

6. Obtenir des profils actifs

Les profils actifs de Spring pilotent le comportement de l'annotation@Profile pour l'activation / la désactivation des beans. Cependant, nous pouvons également souhaiter accéder à la liste des profils actifs par programme.

Nous avons deux façons de le faire,using Environment or*spring.active.profile*.

6.1. Utilisation deEnvironment

On peut accéder aux profils actifs depuis l'objetEnvironment en l'injectant:

public class ProfileManager {
    @Autowired
    private Environment environment;

    public void getActiveProfiles() {
        for (String profileName : environment.getActiveProfiles()) {
            System.out.println("Currently active profile - " + profileName);
        }  
    }
}

6.2. Utilisation despring.active.profile

Alternativement, nous pourrions accéder aux profils en injectant la propriétéspring.profiles.active:

@Value("${spring.profiles.active}")
private String activeProfile;

Ici, notre variableactiveProfilewill contain the name of the profile that is currently active, et s'il y en a plusieurs, elle contiendra leurs noms séparés par une virgule.

Cependant, nous devrionsconsider what would happen if there is no active profile at all. Avec notre code ci-dessus, l'absence de profil actif empêcherait la création du contexte de l'application. Cela entraînerait unIllegalArgumentException dû à l'espace réservé manquant pour l'injection dans la variable.

Afin d'éviter cela, nous pouvonsdefine a default value:

@Value("${spring.profiles.active:}")
private String activeProfile;

Maintenant, si aucun profil n'est actif, nosactiveProfile contiendront juste une chaîne vide. Et, si nous voulons accéder à la liste d'entre eux comme dans l'exemple précédent, nous pouvons le faire ensplitting la variableactiveProfile:

public class ProfileManager {
    @Value("${spring.profiles.active:}")
    private String activeProfiles;

    public String getActiveProfiles() {
        for (String profileName : activeProfiles.split(",")) {
            System.out.println("Currently active profile - " + profileName);
        }
    }
}

7. Exemple d'utilisation de profils

Maintenant que les bases ne sont plus là, jetons un œil à un exemple réel.

Prenons un scénario dans lequel nous devons conserver la configuration de la source de données pour les environnements de développement et de production. Créons une interface communeDatasourceConfig qui doit être implémentée par les deux implémentations de source de données:

public interface DatasourceConfig {
    public void setup();
}

Voici la configuration de l'environnement de développement:

@Component
@Profile("dev")
public class DevDatasourceConfig implements DatasourceConfig {
    @Override
    public void setup() {
        System.out.println("Setting up datasource for DEV environment. ");
    }
}

Et configuration pour l'environnement de production:

@Component
@Profile("production")
public class ProductionDatasourceConfig implements DatasourceConfig {
    @Override
    public void setup() {
       System.out.println("Setting up datasource for PRODUCTION environment. ");
    }
}

Créons maintenant un test et injectons notre interface DatasourceConfig; en fonction du profil actif, Spring injecteraDevDatasourceConfig ouProductionDatasourceConfig bean:

public class SpringProfilesWithMavenPropertiesIntegrationTest {
    @Autowired
    DatasourceConfig datasourceConfig;

    public void setupDatasource() {
        datasourceConfig.setup();
    }
}

Lorsque le profil «dev» est actif, le ressort injecte l'objetDevDatasourceConfig, et à l'appel de la méthodesetup(), la sortie suivante est:

Setting up datasource for DEV environment.

8. Profils dans Spring Boot

Spring Boot prend en charge toute la configuration de profil décrite jusqu'ici, avec quelques fonctionnalités supplémentaires.

Le paramètre d'initialisationspring.profiles.active, introduit dans la section 4, peut également être configuré en tant que propriété dans Spring Boot pour définir les profils actuellement actifs. C'est une propriété standard que Spring Boot récupérera automatiquement:

spring.profiles.active=dev

Pour définir des profils par programmation, nous pouvons également utiliser la classeSpringApplication:

SpringApplication.setAdditionalProfiles("dev");

Pour définir des profils à l'aide de Maven dans Spring Boot, nous pouvons spécifier des noms de profil sousspring-boot-maven-plugin danspom.xml:


    
        org.springframework.boot
        spring-boot-maven-plugin
        
            
                dev
            
        
    
    ...

Et exécutez l'objectif Maven spécifique à Spring Boot:

mvn spring-boot:run

Mais la fonctionnalité la plus importante liée aux profils qu'apporte Spring Boot estprofile-specific properties files. Ceux-ci doivent être nommés au formatapplications-{profile}.properties.

Spring Boot chargera automatiquement les propriétés dans un fichierapplication.properties pour tous les profils, et celles des fichiers.properties spécifiques au profil uniquement pour le profil spécifié.

Par exemple, nous pouvons configurer différentes sources de données pour les profilsdev etproduction en utilisant deux fichiers nommésapplication-dev.properties etapplication-production.properties:

Dans le fichierapplication-production.properties, nous pouvons configurer une source de donnéesMySql:

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/db
spring.datasource.username=root
spring.datasource.password=root

Ensuite, nous pouvons configurer les mêmes propriétés pour le profildev dans le fichierapplication-dev.properties, pour utiliser une base de donnéesH2 en mémoire:

spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
spring.datasource.username=sa
spring.datasource.password=sa

De cette manière, nous pouvons facilement fournir différentes configurations pour différents environnements.

9. Conclusion

Dans ce rapide tutoriel, nous avons expliqué commentdefine a profile sur un bean et comment puisenable the right profiles dans notre application.

Enfin, nous avons validé notre compréhension des profils avec un exemple simple mais réaliste.

L'implémentation de ce tutoriel Spring Security REST se trouve dansthe GitHub project - il s'agit d'un projet basé sur Maven, il devrait donc être facile à importer et à exécuter tel quel.