Автор оригинала: Eric Goebelbecker.
1. Обзор
В этом уроке мы рассмотрим Flips, библиотеку, которая реализует флаги функций в виде мощных аннотаций для приложений Spring Core, Spring MVC и Spring Boot.
Флаги функций (или переключатели) – это шаблон для быстрой и безопасной доставки новых функций. Эти переключатели позволяют нам изменять поведение приложения без изменения или развертывания нового кода. В блоге Мартина Фаулера есть очень информативная статья о флагах функций здесь .
2. Зависимость Maven
Прежде чем мы начнем, нам нужно добавить библиотеку Flips в ваш pom.xml:
com.github.feature-flip flips-core 1.0.1
Maven Central имеет последнюю версию библиотеки , а проект Github находится здесь .
Конечно, нам также нужно включить пружину:
org.springframework.boot spring-boot-starter-web 1.5.10.RELEASE
Поскольку Flips еще не совместим с Spring версии 5.x, мы собираемся использовать последнюю версию Spring Boot в ветке 4.x .
3. Простой сервис ОТДЫХА для переворотов
Давайте соберем простой проект Spring Boot для добавления и переключения новых функций и флагов.
Наше приложение REST обеспечит доступ к Продуктам питания ресурсам:
public class Foo { private String name; private int id; }
Мы просто создадим Сервис , который поддерживает список Продуктов :
@Service public class FlipService { private Listfoos; public List getAllFoos() { return foos; } public Foo getNewFoo() { return new Foo("New Foo!", 99); } }
Мы будем ссылаться на дополнительные методы обслуживания по ходу работы, но этого фрагмента должно быть достаточно, чтобы проиллюстрировать, что Flip Service делает в системе.
И, конечно, нам нужно создать контроллер:
@RestController public class FlipController { private FlipService flipService; // constructors @GetMapping("/foos") public ListgetAllFoos() { return flipService.getAllFoos(); } }
4. Функции управления На основе конфигурации
Самое основное использование Flips-это включение или отключение функции в зависимости от конфигурации. У Flips есть несколько аннотаций для этого.
4.1. Свойство окружающей среды
Давайте представим, что мы добавили новую возможность в Flip Service ; получение Дураков по их идентификатору.
Давайте добавим новый запрос к контроллеру:
@GetMapping("/foos/{id}") @FlipOnEnvironmentProperty( property = "feature.foo.by.id", expectedValue = "Y") public Foo getFooById(@PathVariable int id) { return flipService.getFooById(id) .orElse(new Foo("Not Found", -1)); }
Свойство @FlipOnEnvironmentProperty определяет, доступен ли этот API.
Проще говоря, когда feature.foo.by.id is Y , мы можем делать запросы по идентификатору. Если это не так (или вообще не определено), Flips отключит метод API.
Если функция не включена, будут выполняться сальто FeatureNotEnabledException и Spring вернет “Не реализованный” клиенту REST.
Когда мы вызываем API со свойством , установленным в N , это то, что мы видим:
Status = 501 Headers = {Content-Type=[application/json;charset=UTF-8]} Content type = application/json;charset=UTF-8 Body = { "errorMessage": "Feature not enabled, identified by method public com.baeldung.flips.model.Foo com.baeldung.flips.controller.FlipController.getFooById(int)", "className":"com.baeldung.flips.controller.FlipController", "featureName":"getFooById" }
Как и ожидалось, Spring ловит исключение FeatureNotEnabledException и возвращает клиенту статус 501.
4.2. Активный профиль
Весна уже давно дала нам возможность сопоставлять бобы с различными профилями , такими как dev , test или prod . Расширение этой возможности для сопоставления флагов функций с активным профилем имеет интуитивный смысл.
Давайте посмотрим, как функции включаются или отключаются в зависимости от активного профиля Spring:
@RequestMapping(value = "/foos", method = RequestMethod.GET) @FlipOnProfiles(activeProfiles = "dev") public List getAllFoos() { return flipService.getAllFoos(); }
Аннотация @FlipOnProfiles принимает список имен профилей. Если активный профиль находится в списке, API доступен.
4.3. Весенние выражения
Язык выражений Spring (SpEL) является мощным механизмом для управления средой выполнения. У Flips также есть способ переключать функции с помощью него.
@FlipOnSpringExpression переключает метод, основанный на выражении SpEL, которое возвращает логическое значение.
Давайте используем простое выражение для управления новой функцией:
@FlipOnSpringExpression(expression = "(2 + 2) == 4") @GetMapping("/foo/new") public Foo getNewFoo() { return flipService.getNewFoo(); }
4.4. Отключить
Чтобы полностью отключить функцию, используйте @FlipOff :
@GetMapping("/foo/first") @FlipOff public Foo getFirstFoo() { return flipService.getLastFoo(); }
В этом примере get First Foo() полностью недоступен.
Как мы увидим ниже, мы можем комбинировать аннотации Flips, что позволяет использовать @FlipOff для отключения функции в зависимости от среды или других критериев.
5. Функции Управления С Датой/Временем
Сальто может переключать функцию в зависимости от даты/времени или дня недели. Привязка доступности новой функции к дню или дате имеет очевидные преимущества.
5.1. Дата и время
@FlipOnDateTime принимает имя свойства, отформатированного в формате ISO 8601 .
Итак, давайте установим свойство, указывающее на новую функцию, которая будет активна 1 марта:
first.active.after=2018-03-01T00:00:00Z
Затем мы напишем API для получения первого Foo:
@GetMapping("/foo/first") @FlipOnDateTime(cutoffDateTimeProperty = "first.active.after") public Foo getFirstFoo() { return flipService.getLastFoo(); }
Сальто проверит названное свойство. Если свойство существует и указанная дата/время прошли, функция включена.
5.2. День недели
Библиотека предоставляет @FlipOnDaysOfWeek , что полезно для таких операций, как A/B тестирование:
@GetMapping("/foo/{id}") @FlipOnDaysOfWeek(daysOfWeek={DayOfWeek.MONDAY, DayOfWeek.WEDNESDAY}) public Foo getFooByNewId(@PathVariable int id) { return flipService.getFooById(id).orElse(new Foo("Not Found", -1)); }
getFooByNewId() доступен только по понедельникам и средам.
6. Замените боб
Включение и выключение методов полезно, но мы можем захотеть ввести новое поведение с помощью новых объектов. @FlipBean направляет Flips для вызова метода в новом компоненте.
Аннотация Flips может работать на любом компоненте Spring @. До сих пор мы только изменили наш @RestController , давайте попробуем изменить наш Сервис.
Мы создадим новый сервис с другим поведением от Флип Сервис :
@Service public class NewFlipService { public Foo getNewFoo() { return new Foo("Shiny New Foo!", 100); } }
Мы заменим старый сервис get New Foo() на новую версию:
@FlipBean(with = NewFlipService.class) public Foo getNewFoo() { return new Foo("New Foo!", 99); }
Flips будет направлять вызовы в get New Thing() в Новую службу Flip. @FlipBean – это еще один переключатель, который наиболее полезен в сочетании с другими. Давайте посмотрим на это сейчас.
7. Комбинирование переключателей
Мы объединяем переключатели, указывая более одного. Флипс оценивает их последовательно, с неявной логикой “И”. Поэтому все они должны быть истинными, чтобы включить эту функцию.
Давайте объединим два наших предыдущих примера:
@FlipBean( with = NewFlipService.class) @FlipOnEnvironmentProperty( property = "feature.foo.by.id", expectedValue = "Y") public Foo getNewFoo() { return new Foo("New Foo!", 99); }
Мы воспользовались новым сервисом.
8. Заключение
В этом кратком руководстве мы создали простую службу загрузки Spring и включали и выключали API с помощью аннотаций Flips. Мы видели, как функции переключаются с помощью информации о конфигурации и даты/времени, а также как функции могут переключаться путем замены компонентов во время выполнения.
Примеры кода, как всегда, можно найти на GitHub .