[JAVA] Un exemple d'astuce lorsque vous souhaitez diviser la valeur de la définition en fonction de l'environnement mais ne voulez pas en être conscient

introduction

En ce qui concerne les valeurs telles que les informations de destination de connexion et les informations d'authentification à la base de données et au serveur externe, il est très courant de vouloir avoir des valeurs différentes pour la valeur pour le développement et la valeur pour l'opération de production. À ce moment-là, dans le même fichier de définition

conf.properties


 #Destination de la connexion de production
 #url=http://example.com/
 #Tester la destination de la connexion
 url=http://test.example.com/

Je vois parfois des gens qui écrivent comme ça et les traitent en remplaçant des commentaires, mais il y a diverses choses comme écrire une valeur constante solide du côté du code source (bien qu'il n'y ait aucune raison claire de le faire). Bien qu'elle soit bien meilleure que la malheureuse, ce n'est pas une très bonne méthode. La raison principale est que vous devez savoir de quel côté se trouve le contenu du fichier de définition actuel. Personne ne veut imaginer un accident où il a accidentellement oublié de recommander un fichier de définition et exposé ce qui était connecté à la connexion de test pour la production. S'il s'agit d'un cadre bien conçu aujourd'hui, il y en a qui répondent correctement aux demandes de ce domaine, mais cette fois je voudrais écrire un exemple qui ne dépend pas du cadre et qui ne demande pas beaucoup de temps et d'efforts. Je vais.

code

Configures.java


import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.Properties;

/**
 *Conteneur de valeur définie
 */
public class Configures {
    /**Nom de la clé de propriété système*/
    public static final String PropKey = "Config";

    private static final Properties config = new Properties();

    /**
     *Initialisation
     * @param filePath Chemin d'accès au fichier de définition
     */
    synchronized public static void initialize(String filePath) {
        try {
            load(new FileInputStream(filePath));
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     *Initialisation
     * @param dans le flux vers le fichier de définition
     */
    synchronized public static void initialize(InputStream in) {
        load(in);
    }

    private static void load(InputStream in) {
        try {
            config.load(in);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     *Lire la valeur de la définition
     * @élément clé param
     * @valeur de définition de retour
     */
    public static String get(Environment key) {
        return get(key, null);
    }

    /**
     *Lire la valeur de la définition
     * @élément clé param
     * @param defaultValue Valeur initiale
     * @valeur de définition de retour
     */
    public static String get(Environment key, String defaultValue) {
        if (key == null) {
            throw new IllegalArgumentException("Environment is null");
        }
        return config.getProperty(key.getPropertyKey(), defaultValue);
    }

    private Configures() {
    }
}

Environment.java


/**
 *Éléments clés du fichier de définition
 */
public enum Environment {

    /**URL de destination de la connexion*/
    ConnectUrl("url"),;

    private final String key;

    /**
     *constructeur
     * @param key Nom de la clé dans le fichier de définition
     */
    private Environment(String key) {
        this.key = key;
    }

    /**
     *Obtenir la clé de propriété
     * @retour du nom de la clé
     */
    public String getPropertyKey() {
        return getPropertyKey(System.getProperty(Configures.PropKey));
    }

    /**
     *Obtenir la clé de propriété
     * @paramètre nom d'environnement d'envName
     * @retour du nom de la clé
     */
    public String getPropertyKey(String envName) {
        if (envName == null || "".equals(envName)) {
            return key;
        }
        return String.format("%s.%s", key, envName);
    }
}

Comment utiliser

Après avoir préparé le fichier de définition comme suit

conf.properties


 url=http://localhost/
 url.Test=http://test.example.com/
 url.Release=http://example.com/

Définissez la propriété système "Config" avec la valeur "Release" dans l'environnement de production. (* Je pense qu'il est plus simple d'ajouter "-DConfig = Release" aux variables d'environnement d'exécution)

Dans le vrai code, au début du processus

 Configures.initialize(....)

(Pour les applications Web, il est préférable d'utiliser autour de ServletContextListener)

 String url = Configures.get(Environment.ConnectUrl);

Ensuite, dans l'environnement où la propriété système n'est pas définie, la valeur de "http: // localhost /" et dans l'environnement de production, "http://example.com/" sera renvoyée.

Dans la classe de cas de test, etc., dans la méthode de configuration

 System.setProperty(Configures.PropKey, "Test");

Si vous le faites, la valeur de "http://test.example.com/" sera transmise.

Recommended Posts

Un exemple d'astuce lorsque vous souhaitez diviser la valeur de la définition en fonction de l'environnement mais ne voulez pas en être conscient
Une collection de modèles dont vous voulez être conscient pour ne pas compliquer le code
Un mémo lorsque vous souhaitez effacer la partie horaire de l'agenda
Solution Pay.JP lorsqu'elle fonctionne localement mais ne fonctionne pas bien en environnement de production
Lorsque vous souhaitez modifier le libellé à afficher lors de la création d'une zone de sélection à partir d'énumération
[Swift] Lorsque vous voulez savoir si le nombre de caractères dans String correspond à un certain nombre ...
Est-il facile à utiliser pour l'utilisateur lors de la mise en œuvre de fonctions à usage général? Soyons conscients de
Il doit être identique à l'exemple lors de la connexion à Twitter, mais une erreur se produit jusqu'à la résolution
[RSpec] Lorsque vous souhaitez utiliser la variable d'instance du contrôleur dans le test [attribuer n'est pas recommandé]
La première chose à faire lorsque vous voulez être satisfait d'Heroku sur GitHub avec Eclipse sur Java
Que faire si l'opération non autorisée s'affiche lors de l'exécution d'une commande dans le terminal
[Rails] Que faire si vous obtenez une erreur indiquant "Impossible de trouver un moteur d'exécution JavaScript." Lors de l'exécution de la commande rails dans Catalina
La fin de la programmation catastrophique # 01 "Faites-le avec la valeur absolue d'un entier"
[Petite histoire Java] Surveiller lorsqu'une valeur est ajoutée à la liste
Que faire si le message "Un serveur est déjà en cours d'exécution" s'affiche. Erreur lors de la tentative de démarrage du serveur rails
[Note] [Débutant] Comment écrire lors de la modification de la valeur d'un élément de tableau dans une phrase répétée de Ruby
Une solution à une erreur qui vous met en colère parce que vous ne suivez pas le paramètre par défaut de MySQL ONLY_FULL_GROUP_BY en production et qu'il n'est pas unique
Que faire quand est invalide car il ne commence pas par un "-"
Que faire lorsque «Impossible de trouver» dans l’une des sources apparaît dans l’environnement de développement avec Docker × Rails × RSpec
[outil java] Un outil utile lorsque vous souhaitez envoyer régulièrement le journal ipmsg de PC-A au PC spécifié.
Que faire si vous obtenez une erreur indiquant "Veuillez saisir une valeur valide" lors de l'obtention avec Rails datetime_field
[Rails] Que faire lorsque vous souhaitez générer une erreur qui ne peut pas être annulée lorsque des restrictions de clé externe sont appliquées
Que faire si le message d'erreur "Impossible de trouver un moteur d'exécution JavaScript" s'affiche lors du démarrage du serveur rails