Анотация на пролетта @ConditionalOnProperty

1. Общ преглед

В този кратък урок ще хвърлим светлина върху основната цел на анотацията @ConditionalOnProperty .

Първо, ще започнем с малко предистория за това какво е @ConditionalOnProperty . След това ще разгледаме някои практически примери, за да разберем как работи и какви функции носи.

2. Целта на @ConditionalOnProperty

Обикновено, когато разработваме приложения, базирани на Spring, може да се наложи да създадем някои компоненти условно въз основа на присъствието и стойността на свойството на конфигурацията .

Например, може да поискаме да регистрираме компонент DataSource, който да сочи към производствена или тестова база данни, в зависимост от това дали задаваме стойност на свойството на „prod“ или „test“.

За щастие постигането на това не е толкова трудно, колкото може да изглежда на пръв поглед. Структурата Spring осигурява анотацията @ConditionalOnProperty точно за тази цел.

Накратко, @ConditionalOnProperty позволява регистрация на боб само ако присъства свойство на околната среда и има определена стойност. По подразбиране посоченото свойство трябва да бъде дефинирано и да не е равно на false .

Сега, когато сме запознати с целта на анотацията @ConditionalOnProperty , нека се задълбочим, за да видим как работи.

3. Анотацията @ConditionalOnProperty на практика

За да илюстрираме използването на @ConditionalOnProperty, ще разработим основна система за уведомяване. За да улесним нещата засега, нека приемем, че искаме да изпращаме известия по имейл.

Първо, ще трябва да създадем проста услуга за изпращане на съобщение за известие. Например, помислете за интерфейса NotificationSender :

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

След това нека предоставим изпълнение на интерфейса NotificationSender за изпращане на имейлите ни:

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

Сега да видим как да използваме анотацията @ConditionalOnProperty . Нека конфигурираме зърното NotificationSender по такъв начин, че да бъде заредено само ако е дефинирано свойството уведомление.сервиз :

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

Както виждаме, атрибутите на префикса и името се използват за означаване на свойството на конфигурацията, което трябва да бъде проверено .

Накрая трябва да добавим и последното липсващо парче от пъзела. Нека дефинираме собственото си свойство във файла application.properties :

notification.service=email

4. Разширена конфигурация

Както вече разбрахме, анотацията @ConditionalOnProperty ни позволява да регистрираме условно боб в зависимост от наличието на свойство на конфигурацията.

С тази анотация обаче можем да направим нещо повече от това . И така, нека изследваме!

Да предположим, че искаме да добавим друга услуга за уведомяване - например услуга, която ще ни позволи да изпращаме SMS известия.

За да направим това, трябва да създадем друго изпълнение на NotificationSender :

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

Тъй като имаме две реализации, нека видим как можем да използваме @ConditionalOnProperty, за да заредим правилно правилния боб NotificationSender условно.

За тази цел анотацията предоставя атрибута havingValue . Доста интересно е, че той определя стойността, която дадено свойство трябва да има, за да бъде добавен конкретен боб към контейнера Spring .

Сега, нека уточним при какво условие искаме да регистрираме изпълнението на SmsNotification в контекста:

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

С помощта на атрибута havingValue ясно дадохме да се разбере, че искаме да заредим SmsNotification само когато съобщението service.service е настроено на sms .

Струва си да се спомене, че @ConditionalOnProperty има още един атрибут, наречен matchIfMissing . Този атрибут указва дали условието трябва да съвпада в случай, че свойството не е налично .

Сега, нека съберем всички парчета и напишем прост тестов случай, за да потвърдим, че всичко работи както се очаква:

@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. Заключение

В този кратък урок подчертахме целта на използването на анотацията @ConditionalOnProperty . След това показахме, чрез практически пример, как да го използваме, за да заредим условно Spring Spring.

Както винаги, пълният изходен код на този урок е достъпен в GitHub.