[FIXED] Bedingtes Aktivieren einer externen Systemintegration in Spring Boot

Ausgabe

Ich versuche, Unterstützung für mehrere alternative Integrationen in externe Systeme in einer Spring Boot-App zu implementieren. Die Idee ist, dass eine bestimmte Umgebungsvariable definiert, welche Integration verwendet wird (es kann immer nur eine aktiviert sein), und Spring Boot initialisiert nur die Komponenten ( @Configuration, @Service, @RestControllerusw.), die für diese Integration spezifisch sind. Gibt es dafür einen Best-Practice-Ansatz?

Momentan denke ich an so etwas:

  • Erstellen Sie eine @ConfigurationKlasse pro Integration, kommentieren Sie sie mit @ConditionalOnProperty. Lesen Sie alle relevanten Umgebungsvariablen während der App-Initialisierung, validieren Sie sie und verhindern Sie, dass die App gestartet wird, wenn die Konfigurationen ungültig sind.
  • Kommentieren Sie alle anderen Komponenten, die sich auf diese bestimmte Integration beziehen, mit @ConditionalOnBeanund machen Sie sie abhängig von der zu initialisierenden Konfigurations-Bean.

Vereinfachtes Beispiel:

@Configuration
@ConditionalOnProperty(prefix = "integration", name = "name", havingValue = "FOO")
class FooConfig {
    // Read environment variables etc.
}

@Service
@ConditionalOnBean(FooConfig.class)
class FooService implements ExternalSystemIntegration {

    @Inject
    // Inject the configuration to get access to the relevant environment variables
    public FooService(FooConfig config, ...) { ... }

    @Override
    public void doIt() { ... }
}

Erscheint Ihnen dieser Ansatz sinnvoll, oder sehen Sie darin einige Probleme? Ein (kleiner) Nachteil ist, dass nicht sofort klar ist, welche Komponenten zu einer bestimmten Integration gehören (Sie müssen herausfinden, welche Komponenten von der Konfigurations-Bean abhängen).

Eine alternative Lösung wäre, nur eine Konfigurationsklasse mit einer Reihe von @BeanMethoden zu erstellen, die die verschiedenen @Conditional*Anmerkungen verwenden würden, um zu steuern, welche Komponenten initialisiert werden sollen. Dies würde jedoch erfordern, dass die Abhängigkeiten den erstellten Beans manuell zugeführt werden (da wir die Konstruktorinjektion verwenden), was ich sehr gerne vermeiden möchte. Und ich bin mir nicht sicher, ob es eine gute Möglichkeit gibt, mit dieser Lösung zu steuern, welche Umgebungsvariablen während des App-Bootstrappings gelesen und validiert werden sollen.

Lösung

@Conditional...Bean-Definitionen sind in der Tat der typische Ansatz dafür, und Ihr Ansatz klingt vernünftig. Wenn Sie befürchten, dass es schwierig sein könnte, herauszufinden, welche Komponenten von der Konfigurations-Bean abhängen, können Sie Folgendes tun:

  • Deklarieren Sie Ihre eigene @ConditionalAnmerkung, sodass Sie alle übereinstimmenden Komponenten finden können, indem Sie nach der Verwendung dieser Anmerkung suchen, oder
  • Verschieben Sie alle Bean-Definitionen, die eine Bedingung gemeinsam haben, in eine Konfigurationsklasse mit dieser Bedingung, und deklarieren Sie die Dienste mit Java-basierter Konfiguration. Der Nachteil ist, dass die Java-basierte Konfiguration die Konstruktorinjektion etwas ausführlich macht.
  • oder Sie könnten diese in separate Pakete verschieben und bedingtes Komponenten-Scannen verwenden, um nur die gewünschten Beans aufzunehmen. Dies ist jedoch nur dann einfach, wenn sich die bedingten Pakete außerhalb Ihres normalen Paketstamms befinden, was in den meisten Fällen übertrieben ist.


Beantwortet von –
Verdienst


Antwort geprüft von –
Mary Flores (FixError Volunteer)

0 Shares:
Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like