Spring

[Spring] WebFlux - Mono의 동작방식과 block()

별토끼. 2021. 3. 1. 01:39
반응형

*토비의봄 12회, 13회 를 바탕으로 정리하였습니다

SpringWebflux

Mono

  • Webflux의 대표적 return 타입
  • 파라미터를 한번에 전달하고, 한번에 받아온다.
  • Mono 안에 들어가서 이를 반환하다. (일종의 컨테이너 느낌, List, Optional, Stream 등..)
    @GetMapping("/rest")
    public Mono<String> rest(int idx) {
        String s = "Hello";
        Mono<String> m = Mono.just("Hello"); //Mono가 제공하는 기능들 사용이 가능해짐
        return Mono.just("hello");
    }
  • Publisher는 Subscriber가 구독하지 않으면 데이터를 전송하지 않는다.
  • Mono로 리턴하면 그때 Spring 자체에서 Subscribe 동작 시작

flatMap을 이용한 체이닝

  • map
    단일 스트림의 원소를 매핑시킨 후 매핑시킨 값을 다시 스트림으로 반환하는 중간 연산
  • flatMap
    반환되는 값을 단일 Object로 리턴한다
public class DemoApplication {
    static final String URL1 = "http://localhost:8081/service?req={req}";
    static final String URL2 = "http://localhost:8081/service2?req={req}";

    @GetMapping("/rest")
    public Mono<String> rest(int idx) {
        return client.get().uri(URL1, idx).exchange()
                .flatMap(c -> c.bodyToMono(String.class))
                .flatMap(res1->client.get().uri(URL2, res1).exchange())
                .flatMap(c->c.bodyToMono(String.class));
    }
}

Tomcat - 서블릿 기반
Netty - 서블릿에 의존하지 않는다, 가벼운 서버

Mono로 "Hello WebFlux" 띄워보기

별도의 설정을 해주지 않으면 Blocking이나 마찬가지

@SpringBootApplication
@RestController
@Slf4j
public class DemoApplication {
    @GetMapping("/")
    Mono<String> hello(){
        log.info("pos1");
        Mono m = Mono.just("Hello WebFlux").doOnNext(c->log.info(c)).log(); //Publisher -> (Publisher) -> (Publisher) -> Subscriber
        log.info("pos2");
        return m;
    }
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

Mono.just() 경우

  1. pos1 출력

  2. method generateHello() 출력

  3. pos2 출력

  4. Hello Mono 출력

    public class DemoApplication {
     @GetMapping("/")
     Mono<String> hello() {
         log.info("pos1");
         String msg = generateHello();
         Mono m = Mono.just(msg).doOnNext(c -> log.info(c)).log(); //Publisher -> (Publisher) -> (Publisher) -> Subscriber
         log.info("pos2");
         return m;
     }
    
     private String generateHello() {
         log.info("method generateHello()");
         return "Hello Mono";
     }
    
     public static void main(String[] args) {
         SpringApplication.run(DemoApplication.class, args);
     }
    

}


* 로그 출력
```java
2021-03-01 19:43:10.484  INFO 8740 --- [           main] demo.DemoApplication             : Started DemoApplication in 0.801 seconds (JVM running for 1.482)
2021-03-01 19:43:28.456  INFO 8740 --- [ctor-http-nio-2] demo.DemoApplication             : pos1
2021-03-01 19:43:28.456  INFO 8740 --- [ctor-http-nio-2] demo.DemoApplication             : method generateHello()
2021-03-01 19:43:28.458  INFO 8740 --- [ctor-http-nio-2] demo.DemoApplication             : pos2
2021-03-01 19:43:28.471  INFO 8740 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1              : | onSubscribe([Fuseable] FluxPeekFuseable.PeekFuseableSubscriber)
2021-03-01 19:43:28.473  INFO 8740 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1              : | request(unbounded)
2021-03-01 19:43:28.473  INFO 8740 --- [ctor-http-nio-2] demo.DemoApplication             : Hello Mono
2021-03-01 19:43:28.473  INFO 8740 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1              : | onNext(Hello Mono)
2021-03-01 19:43:28.477  INFO 8740 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1              : | onComplete()
반응형