Utilisation de la variable env dans l’application.properties de Spring Boot

Nous travaillons sur une application Web Spring Boot et la firebase database que nous utilisons est MySql ;

Le problème que vous avez peut-être déjà compris est le suivant:

  • Dans application.properties nous ne pouvons pas coder les informations MySql. Comme notre projet sera exécuté dans 3 endroits différents ( local , Jenkins et OpenShift ), nous devons rendre le champ de source de données dynamic dans application.properties (nous soaps qu’il existe différentes manières de le faire, mais nous travaillons actuellement sur cette solution) .

     spring.datasource.url = spring.datasource.username = spring.datasource.password = 

La solution que nous avons trouvée est que nous créons une variable d’environnement système localement et dans la vm Jenkins (en les nommant de la même manière qu’OpenShift les nomme) et en leur atsortingbuant respectueusement les bonnes valeurs:

 export OPENSHIFT_MYSQL_DB_HOST="jdbc:mysql://localhost" export OPENSHIFT_MYSQL_DB_PORT="3306" export OPENSHIFT_MYSQL_DB_USERNAME="root" export OPENSHIFT_MYSQL_DB_PASSWORD="123asd" 

Nous l’avons fait et cela fonctionne. Nous avons également vérifié avec Map env = System.getenv(); que les variables d’environnement peuvent être transformées en variables Java en tant que telles:

 Ssortingng password = env.get("OPENSHIFT_MYSQL_DB_PASSWORD"); Ssortingng userName = env.get("OPENSHIFT_MYSQL_DB_USERNAME"); Ssortingng sqlURL = env.get("OPENSHIFT_MYSQL_DB_HOST"); Ssortingng sqlPort = env.get("OPENSHIFT_MYSQL_DB_PORT"); 

Maintenant, il ne nous rest plus qu’à utiliser ces variables Java dans notre application.properties et c’est ce qui pose problème.

Dans quel dossier et comment devons-nous atsortingbuer les userName password , userName , sqlURL et sqlPort pour que application.properties puisse les voir et comment les inclure dans application.properties ?

Nous avons essayé beaucoup de choses parmi lesquelles:

 spring.datasource.url = ${sqlURL}:${sqlPort}/"nameofDB" spring.datasource.username = ${userName} spring.datasource.password = ${password} 

Pas de chance jusqu’à présent. Nous ne mettons probablement pas ces variables env dans la bonne classe / dossier et les utilisons correctement dans applicatin.properties .

Votre aide est grandement appréciée!!

Merci!

Vous n’avez pas besoin d’utiliser de variables Java. Pour inclure les variables env du système que vous avez spécifiées dans votre question, directement dans le fichier application.properties , vous pouvez utiliser la syntaxe suivante:

 spring.datasource.url = ${OPENSHIFT_MYSQL_DB_HOST}:${OPENSHIFT_MYSQL_DB_PORT}/"nameofDB" spring.datasource.username = ${OPENSHIFT_MYSQL_DB_USERNAME} spring.datasource.password = ${OPENSHIFT_MYSQL_DB_PORT} 

Mais la manière suggérée par @Stefan Isele est plus préférable, car dans ce cas, vous ne devez déclarer qu’un env enviable: spring.profiles.active . Et Spring lit automatiquement le fichier de propriétés approprié par le modèle application-{profile-name}.properties .

La manière la plus simple d’avoir différentes configurations pour différents environnements consiste à utiliser des profils à ressort. Voir configuration externalisée .

Cela vous donne beaucoup de flexibilité, je l’utilise dans mes projets et c’est extrêmement utile. Dans votre cas, vous auriez 3 profils «local», «jenkins» et «openshift»

Vous disposez alors de 3 fichiers de propriétés spécifiques au profil application-local.properties application-jenkins.properties application-openshift.properties

Vous pouvez y définir les propriétés de l’environnement concerné. Lorsque vous exécutez l’application, vous devez spécifier le profil à activer comme -Dspring.profiles.active=jenkins

modifier

Selon le document de spring, il suffit de définir la variable d’environnement du système d’exploitation SPRING_PROFILES_ACTIVE pour activer les profils et ne pas la transmettre en paramètre.

existe-t-il un moyen de transmettre l’option de profil actif pour l’application Web au moment de l’exécution?

Spring détermine les profils actifs comme l’une des premières étapes lors de la création du contexte d’application. Les profils actifs sont ensuite utilisés pour décider quels fichiers de propriétés sont lus et quels beans sont instanciés. Une fois l’application démarrée, cela ne peut pas être modifié.

C’est en réponse à un certain nombre de commentaires que ma réputation n’est pas assez élevée pour pouvoir commenter directement.

Vous pouvez spécifier le profil à l’exécution tant que le contexte d’application n’a pas encore été chargé.

 // Previous answers incorrectly used "spring.active.profiles" instead of // "spring.profiles.active" (as noted in the comments). // Use AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME to avoid this mistake. System.setProperty(AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME, environment); ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/META-INF/spring/applicationContext.xml"); 

Voici un extrait de code à travers une chaîne d’environnements Les fichiers de propriétés sont chargés pour différents environnements.

Fichier de propriétés sous les ressources de votre application ( src / main / resources ): –

  1. application.properties 2. application-dev.properties 3. application-uat.properties 4. application-prod.properties 

Dans l’idéal, application.properties contient toutes les propriétés communes accessibles pour tous les environnements et toutes les propriétés liées à l’environnement ne fonctionnent que dans les environnements spécifiés. Par conséquent, l’ordre de chargement de ces fichiers de propriétés sera le suivant –

  application.properties -> application.{spring.profiles.active}.properties. 

Extrait de code ici: –

  import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; public class PropertiesUtils { public static final Ssortingng SPRING_PROFILES_ACTIVE = "spring.profiles.active"; public static void initProperties() { Ssortingng activeProfile = System.getProperty(SPRING_PROFILES_ACTIVE); if (activeProfile == null) { activeProfile = "dev"; } PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer(); Resource[] resources = new ClassPathResource[] {new ClassPathResource("application.properties"), new ClassPathResource("application-" + activeProfile + ".properties")}; propertySourcesPlaceholderConfigurer.setLocations(resources); } } 

Peut-être que j’écris ceci trop tard, mais j’ai rencontré le même problème lorsque j’ai essayé de remplacer les méthodes de lecture des propriétés.

Mon problème a été: 1) Lecture des propriétés de env si cette propriété a été définie dans env 2) Lecture des propriétés de la propriété du système si cette propriété a été définie dans la propriété système 3) Et enfin, lecture des propriétés de l’application.

Donc, pour résoudre ce problème, je vais à la classe de configuration de mon bean

 @Validated @Configuration @ConfigurationProperties(prefix = ApplicationConfiguration.PREFIX) @PropertySource(value = "${application.properties.path}", factory = PropertySourceFactoryCustom.class) @Data // lombok public class ApplicationConfiguration { static final Ssortingng PREFIX = "application"; @NotBlank private Ssortingng keysPath; @NotBlank private Ssortingng publicKeyName; @NotNull private Long tokenTimeout; private Boolean devMode; public void setKeysPath(Ssortingng keysPath) { this.keysPath = SsortingngUtils.cleanPath(keysPath); } } 

Et écraser l’usine dans @PropertySource. Et puis j’ai créé ma propre implémentation pour les propriétés de lecture.

  public class PropertySourceFactoryCustom implements PropertySourceFactory { @Override public PropertySource createPropertySource(Ssortingng name, EncodedResource resource) throws IOException { return name != null ? new PropertySourceCustom(name, resource) : new PropertySourceCustom(resource); } } 

Et créé PropertySourceCustom

 public class PropertySourceCustom extends ResourcePropertySource { public LifeSourcePropertySource(Ssortingng name, EncodedResource resource) throws IOException { super(name, resource); } public LifeSourcePropertySource(EncodedResource resource) throws IOException { super(resource); } public LifeSourcePropertySource(Ssortingng name, Resource resource) throws IOException { super(name, resource); } public LifeSourcePropertySource(Resource resource) throws IOException { super(resource); } public LifeSourcePropertySource(Ssortingng name, Ssortingng location, ClassLoader classLoader) throws IOException { super(name, location, classLoader); } public LifeSourcePropertySource(Ssortingng location, ClassLoader classLoader) throws IOException { super(location, classLoader); } public LifeSourcePropertySource(Ssortingng name, Ssortingng location) throws IOException { super(name, location); } public LifeSourcePropertySource(Ssortingng location) throws IOException { super(location); } @Override public Object getProperty(Ssortingng name) { if (SsortingngUtils.isNotBlank(System.getenv(name))) return System.getenv(name); if (SsortingngUtils.isNotBlank(System.getProperty(name))) return System.getProperty(name); return super.getProperty(name); } } 

Donc, cela m’a aidé.

En utilisant le contexte Spring 5.0, j’ai réussi à charger le fichier de propriétés correct en fonction de l’environnement système via l’annotation suivante

 @PropertySources({ @PropertySource("classpath:application.properties"), @PropertySource("classpath:application-${MYENV:test}.properties")}) 

Ici, la valeur MYENV est lue à partir de l’environnement système et si l’environnement du système n’est pas présent, le fichier de propriétés de l’environnement de test par défaut sera chargé. Si je donne une valeur MYENV incorrecte, l’application ne démarrera pas.

Remarque: pour chaque profil, vous souhaitez conserver – vous devrez créer un fichier application- [profil] .property et, bien que j’aie utilisé Spring context 5.0 et pas Spring boot – je pense que cela fonctionnera également avec Spring 4.1.