Die Annotation Spring @ConditionalOnProperty

1. Übersicht

In diesem kurzen Tutorial werden wir den Hauptzweck der Annotation @ConditionalOnProperty beleuchten .

Zunächst beginnen wir mit einigen Hintergrundinformationen zu @ConditionalOnProperty . Anschließend sehen wir uns einige praktische Beispiele an, um zu verstehen, wie es funktioniert und welche Funktionen es bietet.

2. Der Zweck von @ConditionalOnProperty

In der Regel müssen wir bei der Entwicklung von Spring-basierten Anwendungen möglicherweise einige Beans abhängig vom Vorhandensein und dem Wert einer Konfigurationseigenschaft erstellen .

Beispielsweise möchten wir möglicherweise eine DataSource- Bean registrieren , um auf eine Produktions- oder Testdatenbank zu verweisen, je nachdem, ob wir einen Eigenschaftswert auf "prod" oder "test" setzen.

Glücklicherweise ist es nicht so schwer, dies zu erreichen, wie es auf den ersten Blick erscheinen mag. Das Spring-Framework bietet genau zu diesem Zweck die Annotation @ConditionalOnProperty .

Kurz gesagt, die @ConditionalOnProperty aktiviert die Bean-Registrierung nur, wenn eine Umgebungseigenschaft vorhanden ist und einen bestimmten Wert hat. Standardmäßig muss die angegebene Eigenschaft definiert sein und darf nicht gleich false sein .

Nachdem wir mit dem Zweck der Annotation @ConditionalOnProperty vertraut sind, wollen wir genauer untersuchen , wie sie funktioniert.

3. Die Annotation @ConditionalOnProperty in der Praxis

Um die Verwendung von @ConditionalOnProperty zu veranschaulichen , werden wir ein grundlegendes Benachrichtigungssystem entwickeln. Nehmen wir an, wir möchten E-Mail-Benachrichtigungen senden, um die Dinge vorerst einfach zu halten.

Zunächst müssen wir einen einfachen Dienst erstellen, um eine Benachrichtigung zu senden. Betrachten Sie beispielsweise die NotificationSender- Schnittstelle:

public interface NotificationSender { String send(String message); }

Als Nächstes stellen wir eine Implementierung der NotificationSender- Oberfläche zum Senden unserer E-Mails bereit:

public class EmailNotification implements NotificationSender { @Override public String send(String message) { return "Email Notification: " + message; } }

Lassen Sie uns nun sehen, wie Sie die Annotation @ConditionalOnProperty verwenden . Konfigurieren Sie die NotificationSender- Bean so, dass sie nur geladen wird, wenn die Eigenschaft notification.service definiert ist :

@Bean(name = "emailNotification") @ConditionalOnProperty(prefix = "notification", name = "service") public NotificationSender notificationSender() { return new EmailNotification(); }

Wie wir sehen können, werden die Attribute Präfix und Name verwendet, um die Konfigurationseigenschaft zu kennzeichnen, die überprüft werden soll .

Schließlich müssen wir das letzte fehlende Puzzleteil hinzufügen. Definieren wir unsere benutzerdefinierte Eigenschaft in der Datei application.properties :

notification.service=email

4. Erweiterte Konfiguration

Wie wir bereits erfahren haben, können wir mit der Annotation @ConditionalOnProperty Beans abhängig vom Vorhandensein einer Konfigurationseigenschaft bedingt registrieren.

Mit dieser Anmerkung können wir jedoch mehr als nur das tun . Also, lasst uns erkunden!

Angenommen, wir möchten einen weiteren Benachrichtigungsdienst hinzufügen, z. B. einen Dienst, mit dem wir SMS-Benachrichtigungen senden können.

Dazu müssen wir eine weitere NotificationSender- Implementierung erstellen :

public class SmsNotification implements NotificationSender { @Override public String send(String message) { return "SMS Notification: " + message; } }

Da wir zwei Implementierungen haben, wollen wir sehen, wie wir @ConditionalOnProperty verwenden können , um die richtige NotificationSender- Bean bedingt zu laden .

Zu diesem Zweck stellt die Annotation das Attribut haveValue bereit . Interessanterweise er definiert den Wert , dass eine Eigenschaft haben muss , um für eine bestimmte Bohne bis zum Frühjahr Container hinzugefügt werden .

Lassen Sie uns nun angeben, unter welcher Bedingung wir die SmsNotification- Implementierung im Kontext registrieren möchten :

@Bean(name = "smsNotification") @ConditionalOnProperty(prefix = "notification", name = "service", havingValue = "sms") public NotificationSender notificationSender2() { return new SmsNotification(); }

Mithilfe des Attributs haveValue haben wir klargestellt, dass SmsNotification nur geladen werden soll , wenn notification.service auf sms eingestellt ist .

Es ist erwähnenswert, dass @ConditionalOnProperty ein weiteres Attribut namens matchIfMissing hat . Dieses Attribut gibt an, ob die Bedingung übereinstimmen soll, falls die Eigenschaft nicht verfügbar ist .

Lassen Sie uns nun alle Teile zusammenfügen und einen einfachen Testfall schreiben, um zu bestätigen, dass alles wie erwartet funktioniert:

@Test public void whenValueSetToEmail_thenCreateEmailNotification() { this.contextRunner.withPropertyValues("notification.service=email") .withUserConfiguration(NotificationConfig.class) .run(context -> { assertThat(context).hasBean("emailNotification"); NotificationSender notificationSender = context.getBean(EmailNotification.class); assertThat(notificationSender.send("Hello From Baeldung!")).isEqualTo("Email Notification: Hello From Baeldung!"); assertThat(context).doesNotHaveBean("smsNotification"); }); }

5. Schlussfolgerung

In diesem kurzen Tutorial haben wir den Zweck der Verwendung der Annotation @ConditionalOnProperty hervorgehoben . Anschließend haben wir anhand eines praktischen Beispiels gezeigt, wie Spring Beans damit bedingt geladen werden können.

Wie immer ist der vollständige Quellcode dieses Tutorials auf GitHub verfügbar.