Frage

Hintergrund: Ich habe also mehrere Beans, die externe Systeme verbinden.Für die Entwicklung ist es praktisch, die externen Systeme zu verspotten und die Schnittstellen-Beans durch einige Implementierungen zu ersetzen, die mehr oder weniger statische Antworten erzeugen.Ich habe also eine Schnittstelle, die eigentliche Implementierung und eine Stub-Implementierung wie folgt erstellt:

public interface ExternalService {
// ...
}

@Service
public class ExternalServiceImpl implements ExternalService {
// ...
}

@Service
@Primary
@Profile({"stub"})
public class StubExternalService implements ExternalService {
// ...
}

...und das funktioniert super:Wenn das Stub-Profil nicht vorhanden ist, wird das Stub-Bean überhaupt nicht geladen.Wenn es vorhanden ist, ersetzt es aufgrund der @Primary-Annotation die tatsächliche Implementierung.

Problem: Jetzt bin ich jedoch zum ersten Mal in einer Situation, in der ich tatsächlich zwei echte Implementierungen derselben Schnittstelle habe.Einer davon ist als primär definiert, der andere kann jedoch auch verwendet werden, indem er aus dem Anwendungskontext geladen wird.

Ich würde immer noch gerne einen Stub-Dienst erstellen, um beide zu ersetzen, aber dieses Mal funktioniert meine alte Methode, den Stub als @Primary zu definieren, nicht, da es bereits eine primäre Implementierung gibt.Grundsätzlich bräuchte ich eine Möglichkeit, die primäre Bean nicht zu laden, wenn das Stub-Profil festgelegt ist, aber ich weiß nicht, wie ich das genau machen soll.Websuchen oder andere Fragen zum Stapelüberlauf scheinen nicht zu helfen.

War es hilfreich?

Lösung

Es stellte sich heraus, dass die Antwort überraschend einfach war:Sie fügen einen Nicht-Operator hinzu (!) vor dem Profilnamen:

@Service
@Primary
@Profile({"!stub"})
public class ExternalServiceImpl implements ExternalService {
// ...
}

Auf diese Weise wird die Bean nur geladen, wenn die stub-profile ist nicht aktiv.Die Unterstützung für diese Funktion wurde hinzugefügt Feder 3,2 M1.

Es gibt jedoch eine Einschränkung:wenn du schreibst @Profile({"!stub", "foo"}), wird das Komma als „oder“ und nicht als „und“ behandelt.Diese Beispiel-Bean würde also in beiden Fällen aktiviert werden stub war nicht aktiv oder wenn foo war aktiv.

Bearbeiten/Hinzufügen: Spring 5.1 fügte eine Unterstützung für a hinzu Neue Ausdruckssprache für Profile: !stub & foo wird aktiviert, wenn stub ist nicht aktiv und foo ist aktiv.Großer Erfolg!Sie können sogar Ands und Ors kombinieren und kombinieren, vorausgesetzt, Sie verwenden Klammern: production & (us-east | eu-central).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top