[JAVA] Ein Beispiel für kleine Arbeiten, bei denen Sie den Definitionswert nach der Umgebung aufteilen möchten, sich dessen jedoch nicht bewusst sein möchten

Einführung

Ich denke, dass es sehr häufig vorkommt, unterschiedliche Werte für Verbindungszielinformationen und Authentifizierungsinformationen für Datenbanken, externe Server usw., für die Entwicklung und für den Produktionsbetrieb zu haben. Zu diesem Zeitpunkt in derselben Definitionsdatei

conf.properties


 #Produktionsverbindungsziel
 #url=http://example.com/
 #Verbindungsziel testen
 url=http://test.example.com/

Ich sehe manchmal Leute, die so etwas wie ... schreiben und damit umgehen, indem sie Kommentare ersetzen, aber es gibt verschiedene Dinge wie das Schreiben eines soliden konstanten Werts auf der Quellcodeseite (obwohl es keinen klaren Grund dafür gibt). Obwohl es weitaus besser ist als das unglückliche, ist es keine sehr gute Methode. Der Hauptgrund ist, dass Sie wissen müssen, für welche Seite der Inhalt der aktuellen Definitionsdatei bestimmt ist. Niemand möchte sich einen Unfall vorstellen, bei dem er versehentlich vergessen hat, eine Definitionsdatei erneut zu empfehlen, und offengelegt hat, was mit der Testverbindung für die Produktion verbunden war. Wenn es sich um ein gut gemachtes Framework von heute handelt, gibt es einige, die angemessen auf die Anforderungen dieses Bereichs reagieren, aber dieses Mal möchte ich ein Beispiel schreiben, das nicht vom Framework abhängt und nicht viel Zeit und Mühe kostet. Ich werde.

Code

Configures.java


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

/**
 *Definierter Wertecontainer
 */
public class Configures {
    /**Name des Systemeigenschaftsschlüssels*/
    public static final String PropKey = "Config";

    private static final Properties config = new Properties();

    /**
     *Initialisieren
     * @param filePath Pfad zur Definitionsdatei
     */
    synchronized public static void initialize(String filePath) {
        try {
            load(new FileInputStream(filePath));
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     *Initialisieren
     * @param in Stream zur Definitionsdatei
     */
    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);
        }
    }

    /**
     *Definitionswert lesen
     * @param key key item
     * @Definitionswert zurückgeben
     */
    public static String get(Environment key) {
        return get(key, null);
    }

    /**
     *Definitionswert lesen
     * @param key key item
     * @param defaultValue Anfangswert
     * @Definitionswert zurückgeben
     */
    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


/**
 *Schlüsselelemente in der Definitionsdatei
 */
public enum Environment {

    /**Verbindungsziel-URL*/
    ConnectUrl("url"),;

    private final String key;

    /**
     *Konstrukteur
     * @param key Schlüsselname in der Definitionsdatei
     */
    private Environment(String key) {
        this.key = key;
    }

    /**
     *Eigenschaftsschlüssel abrufen
     * @Name des Rückkehrschlüssels
     */
    public String getPropertyKey() {
        return getPropertyKey(System.getProperty(Configures.PropKey));
    }

    /**
     *Eigenschaftsschlüssel abrufen
     * @param envName Umgebungsname
     * @Name des Rückkehrschlüssels
     */
    public String getPropertyKey(String envName) {
        if (envName == null || "".equals(envName)) {
            return key;
        }
        return String.format("%s.%s", key, envName);
    }
}

Wie benutzt man

Nach dem Vorbereiten der Definitionsdatei wie folgt

conf.properties


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

Definieren Sie die Systemeigenschaft "Config" mit dem Wert "Release" in der Produktionsumgebung. (* Ich denke, es ist am einfachsten, "-DConfig = Release" zu den Laufzeitumgebungsvariablen hinzuzufügen.)

Im realen Code zu Beginn des Prozesses

 Configures.initialize(....)

(Für Webanwendungen ist es besser, ServletContextListener zu verwenden.)

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

In der Umgebung, in der die Systemeigenschaft nicht definiert ist, wird der Wert "http: // localhost /" und in der Produktionsumgebung "http://example.com/" zurückgegeben.

In der Testfallklasse etc., in der Methode zur Einrichtung

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

In diesem Fall wird der Wert "http://test.example.com/" übergeben.

Recommended Posts

Ein Beispiel für kleine Arbeiten, bei denen Sie den Definitionswert nach der Umgebung aufteilen möchten, sich dessen jedoch nicht bewusst sein möchten
Eine Sammlung von Mustern, die Sie kennen möchten, um den Code nicht zu komplizieren
Ein Memo, wenn Sie den Zeitteil des Kalenders löschen möchten
Pay.JP-Lösung, wenn sie lokal funktioniert, aber in der Produktionsumgebung nicht gut funktioniert
Wenn Sie den Wortlaut ändern möchten, der angezeigt werden soll, wenn Sie ein Auswahlfeld aus enum erstellen
[Swift] Wenn Sie wissen möchten, ob die Anzahl der Zeichen in String mit einer bestimmten Anzahl übereinstimmt ...
Ist es für den Benutzer einfach, Allzweckfunktionen zu implementieren? Seien wir uns dessen bewusst
Es sollte mit dem Beispiel identisch sein, wenn Sie sich bei Twitter anmelden, es tritt jedoch ein Fehler auf, bis die Lösung behoben ist
[RSpec] Wenn Sie die Instanzvariable des Controllers im Test verwenden möchten [Zuweisungen wird nicht empfohlen]
Das erste, was Sie tun müssen, wenn Sie mit Heroku auf GitHub mit Eclipse auf Java zufrieden sein möchten
Was tun, wenn der Vorgang nicht zulässig ist, wenn ein Befehl im Terminal ausgeführt wird?
[Rails] Was tun, wenn die Fehlermeldung "JavaScript-Laufzeit konnte nicht gefunden werden?" Angezeigt wird, wenn der Befehl "Rails" in Catalina ausgeführt wird
Das Ende der katastrophalen Programmierung # 01 "Mach es mit dem absoluten Wert einer ganzen Zahl"
[Java small story] Überwachen Sie, wann der Liste ein Wert hinzugefügt wird
Was tun, wenn die Meldung "Ein Server läuft bereits" angezeigt wird. Fehler beim Versuch, den Rails-Server zu starten
[Hinweis] [Anfänger] Schreiben, wenn der Wert eines Array-Elements in einem sich wiederholenden Satz von Ruby geändert wird
Eine Lösung für einen Fehler, der Sie verärgert, dass Sie in einer Produktionsumgebung nicht der MySQL-Standardeinstellung ONLY_FULL_GROUP_BY folgen und diese nicht eindeutig ist.
Was zu tun ist, wenn es ungültig ist, weil es nicht mit einem '-' beginnt
Was ist zu tun, wenn in einer der Quellen in der Entwicklungsumgebung mit Docker × Rails × RSpec "Nicht gefunden" angezeigt wird?
[Java-Tool] Ein nützliches Tool, wenn Sie das IPMSG-Protokoll von PC-A regelmäßig an den angegebenen PC senden möchten.
Was tun, wenn beim Abrufen von Rails datetime_field die Fehlermeldung "Bitte geben Sie einen gültigen Wert ein" angezeigt wird?
[Rails] Was tun, wenn Sie einen Fehler generieren möchten, der nicht behoben werden kann, wenn externe Schlüsselbeschränkungen angewendet werden?
Was tun, wenn die Fehlermeldung "JavaScript-Laufzeit konnte nicht gefunden werden" angezeigt wird? Beim Starten des Rails-Servers