Annotazione Spring @ConditionalOnProperty

1. Panoramica

In questo breve tutorial, faremo luce sullo scopo principale dell'annotazione @ConditionalOnProperty .

Innanzitutto, inizieremo con un po 'di background su cosa sia @ConditionalOnProperty . Quindi, esamineremo alcuni esempi pratici per capire come funziona e quali funzionalità offre.

2. Lo scopo di @ConditionalOnProperty

In genere, durante lo sviluppo di applicazioni basate su Spring, potrebbe essere necessario creare alcuni bean in base alla presenza e al valore di una proprietà di configurazione .

Ad esempio, potremmo voler registrare un bean DataSource in modo che punti a un database di produzione o di test a seconda se impostiamo un valore di proprietà su "prod" o "test".

Fortunatamente, raggiungere questo obiettivo non è così difficile come potrebbe sembrare a prima vista. Il framework Spring fornisce l' annotazione @ConditionalOnProperty proprio a questo scopo.

In breve, @ConditionalOnProperty abilita la registrazione del bean solo se è presente una proprietà di ambiente e ha un valore specifico. Per impostazione predefinita, la proprietà specificata deve essere definita e non uguale a false .

Ora che abbiamo familiarità con lo scopo dell'annotazione @ConditionalOnProperty , approfondiamo per vedere come funziona.

3. L' annotazione @ConditionalOnProperty nella pratica

Per esemplificare l'uso di @ConditionalOnProperty, svilupperemo un sistema di notifica di base. Per mantenere le cose semplici per ora, supponiamo di voler inviare notifiche e-mail.

Innanzitutto, dovremo creare un semplice servizio per inviare un messaggio di notifica. Ad esempio, considera l' interfaccia NotificationSender :

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

Successivamente, forniamo un'implementazione dell'interfaccia NotificationSender per inviare le nostre e-mail:

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

Vediamo ora come utilizzare l' annotazione @ConditionalOnProperty . Configuriamo il bean NotificationSender in modo tale che venga caricato solo se la proprietà notification.service è definita :

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

Come possiamo vedere, gli attributi prefix e name sono usati per denotare la proprietà di configurazione che dovrebbe essere controllata .

Infine, dobbiamo aggiungere l'ultimo pezzo mancante del puzzle. Definiamo la nostra proprietà personalizzata nel file application.properties :

notification.service=email

4. Configurazione avanzata

Come abbiamo già appreso, l' annotazione @ConditionalOnProperty ci consente di registrare i bean in modo condizionale a seconda della presenza di una proprietà di configurazione.

Tuttavia, possiamo fare di più con questa annotazione . Allora esploriamo!

Supponiamo di voler aggiungere un altro servizio di notifica, ad esempio un servizio che ci consentirà di inviare notifiche SMS.

Per fare ciò, dobbiamo creare un'altra implementazione di NotificationSender :

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

Poiché abbiamo due implementazioni, vediamo come possiamo usare @ConditionalOnProperty per caricare condizionatamente il bean NotificationSender corretto .

A tale scopo, l'annotazione fornisce l' attributo havingValue . Molto interessante, esso definisce il valore che una proprietà deve avere per un bean specifico da aggiungere al contenitore della sorgente .

Ora, specifichiamo in quale condizione vogliamo registrare l' implementazione di SmsNotification nel contesto:

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

Con l'aiuto dell'attributo havingValue , abbiamo chiarito che vogliamo caricare SmsNotification solo quando notification.service è impostato su sms .

Vale la pena ricordare che @ConditionalOnProperty ha un altro attributo chiamato matchIfMissing . Questo attributo specifica se la condizione deve corrispondere nel caso in cui la proprietà non sia disponibile .

Ora, mettiamo insieme tutti i pezzi e scriviamo un semplice test case per confermare che tutto funziona come previsto:

@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. conclusione

In questo breve tutorial, abbiamo evidenziato lo scopo dell'utilizzo dell'annotazione @ConditionalOnProperty . Quindi, abbiamo mostrato, attraverso un esempio pratico, come usarlo per caricare i bean Spring in modo condizionale.

Come sempre, il codice sorgente completo di questo tutorial è disponibile su GitHub.