Я хочу участвовать в мире реактивного программирования с помощью Spring. Как я понял, это дает мне выбор между двумя разными парадигмами: основанной на аннотациях (с известными нам @Controller
, @RequestMapping
) и реактивной (который предназначен для устранения "аннотационного ада").
Моя проблема в непонимании того, как будет выглядеть типичный реактивный контроллер. Есть три концептуальных интерфейса, которые я могу использовать в своем классе контроллера:
HandlerFunction<T>
(1) — я определяю метод для каждого конкретного ServerRequest
, который возвращает конкретный экземпляр HandlerFunction<T>
, затем регистрирую эти методы на маршрутизаторе. Верно?
RouterFunction
(2) и FilterFunction
(3) — есть ли конкретное место, куда следует поместить все RequestPredicate
с соответствующими HandlerFunction
? Или я могу сделать это отдельно в каждом контроллере (как я делал с аннотационным подходом)? Если да, то как тогда уведомить глобальный обработчик (маршрутизатор, если есть?), чтобы применить эту часть маршрутизатора с этого контроллера?
Вот как я сейчас вижу «шаблон» реактивного контроллера:
public class Controller {
// handlers
private HandlerFunction<ServerResponse> handleA() {
return request -> ok().body(fromObject("a"));
}
// router
public RouterFunction<?> getRouter() {
return route(GET("/a"), handleA()).and(
route(GET("/b"), handleB()));
}
// filter
public RouterFunction<?> getFilter() {
return route(GET("/c"), handleC()).filter((request, next) -> next.handle(request));
}
}
И, наконец, как сказать, что это контроллер, не пометив его аннотацией?
Я прочитал справку по Spring и все сообщения, связанные с этой проблемой, в официальном блоге. Образцов много, но все они вырваны из контекста (ИМХО) и я не могу собрать их в полную картину.
Я был бы признателен, если бы вы могли привести реальный пример и передовой опыт организации взаимодействия между этими функциями.