使用Project Reactor進行反應式資料流 - spring.io

發表於2021-01-15

Spring團隊開發了Project Reactor,以支援Spring生態系統中的反應式工作。您不需要Spring即可使用Project Reactor,但是Spring生態系統中的所有反應式API均基於Project Reactor來提供資料流選項。

讓我們看一個示例,該示例說明Project Reactor如何簡化不同資料流源和接收器的組合工作,並消除所有手動執行緒化程式碼。

您需要以下依賴項:

org.springframework.boot:spring-boot-starter-webflux

下面示例說明了在給定不同資料型別的情況下標準化處理的難易程度。在此示例中,我們比較一下Java 8的java.util.Stream<T?>和a CompletableFuture<T>,在大多數反應式應用程式中,您不必從事將非反應性型別轉換為反應性型別(如Flux<T>或Mono<T>)的業務。這些例子將更加直接。本示例假定您有兩個資料來源,需要將它們組合在一起。

package bootiful.rx;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.concurrent.CompletableFuture;
import java.util.stream.Stream;

@SpringBootApplication
public class BootifulApplication {

    CompletableFuture<String> returnCompletableFuture(int counter) {
        return CompletableFuture.supplyAsync(() -> {
            var start = System.currentTimeMillis();
            try {
                Thread.sleep((long) (Math.max((Math.random() * 10), 5) * 1000));
            }
            catch (InterruptedException e) {
                // threads smdh
            }
            var stop = System.currentTimeMillis();
            var delta = stop - start;
            return "(" + Thread.currentThread().getName() + ") Hello, #" + counter + "! (after " + delta + " ms.)";
        });
    }

    Stream<Integer> returnStream() {
        return Stream.iterate(0, integer -> integer + 1);
    }

    @Bean
    ApplicationListener<ApplicationReadyEvent> begin() {
        return event -> {

            Flux<String> count = Flux//
                    .fromStream(this.returnStream()) //
                    .take(10) //
                    .flatMap(c -> Flux.zip(Mono.just(c), Mono.fromCompletionStage(this.returnCompletableFuture(c)))) //
                    .map(tuple -> tuple.getT2() + " #" + tuple.getT1()); //

            count.subscribe(System.out::println);
        };
    }

    public static void main(String[] args) {
        SpringApplication.run(BootifulApplication.class, args);
    }

}

 

相關文章