Статьи

Реактор проекта развернуть метод

Один из моих коллег по работе недавно познакомил меня с оператором расширения типов Project Reactor, и в этом посте я хочу рассказать о нескольких способах его использования.

Развертывание разбитого на страницы результата

Рассмотрим репозиторий на основе Spring Data для модели с названием City:

1
2
3
4
5
import org.springframework.data.jpa.repository.JpaRepository;
import samples.geo.domain.City;
 
public interface CityRepo extends JpaRepository<City, Long> {
}

Этот репозиторий предоставляет способ получения разбитого на страницы результата по следующим строкам:

1
cityRepo.findAll(PageRequest.of(0, 5))

Теперь, если бы мне пришлось развернуть несколько страниц в результате, способ сделать это был бы следующим видом цикла:

1
2
3
4
5
6
var pageable: Pageable = PageRequest.of(0, 5)
do {
    var page: Page<City> = cityRepo.findAll(pageable)
    page.content.forEach { city -> LOGGER.info("City $city") }
    pageable = page.nextPageable()
} while (page.hasNext())

Эквивалентное развертывание разбитого на страницы результата можно выполнить с помощью оператора расширения Reactor следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
val result: Flux<City> =
    Mono
        .fromSupplier { cityRepo.findAll(PageRequest.of(0, 5)) }
        .expand { page ->
            if (page.hasNext())
                Mono.fromSupplier { cityRepo.findAll(page.nextPageable()) }
            else
                Mono.empty()
        }
        .flatMap { page -> Flux.fromIterable(page.content) }
 
result.subscribe(
    { page -> LOGGER.info("City ${page}") },
    { t -> t.printStackTrace() }
)

Здесь первая страница результатов расширяется до второй страницы, вторая страница — до третьей страницы и т. Д. До тех пор, пока не будет страниц для извлечения.

Обход дерева

Рассмотрим узел в древовидной структуре, представленной следующей моделью:

1
2
3
4
data class Node(
    val id: String,
    val nodeRefs: List<String>,
)

Пример данных, который выглядит следующим образом:

может быть пройден с помощью вызова, который выглядит следующим образом:

1
2
3
4
5
6
val rootMono: Mono<Node> = nodeService.getNode("1")
val expanded: Flux<Node> = rootMono.expand { node ->
    Flux.fromIterable(node.childRefs)
        .flatMap { nodeRef -> nodeService.getNode(nodeRef) }
}
expanded.subscribe { node -> println(node) }

Это расширение в ширину, вывод выглядит так:

1
2
3
4
5
6
7
Node-1
Node-1-1
Node-1-2
Node-1-1-1
Node-1-1-2
Node-1-2-1
Node-1-2-2

Вариант expandDeep будет проходить в глубину

Смотрите оригинальную статью здесь: Project Reactor, разверните метод

Мнения, высказанные участниками Java Code Geeks, являются их собственными.