토비의 봄 TV 13회 스프링 리액티브 프로그래밍 (9) Mono의 동작방식과 block()IT/Spring Framework2018. 2. 3. 23:56
Table of Contents
(시청일 : 20170114)
- 스프링 5.0 WebFlux에서 사용되는 Reactor의 Mono의 기본 동작방식을 살펴봅니다.
■ 예제 1
package toby;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
@SpringBootApplication
@RestController
@Slf4j
public class Toby013Application {
@GetMapping("/")
Mono<String> hello() {
return Mono.just("Hello WebFlux").log(); // Publisher -> (Publisher) -> (Publisher) -> Subscriber
}
public static void main(String[] args) {
SpringApplication.run(Toby013Application.class, args);
}
}
<결과>
2018-01-21 17:15:04.761 INFO 8148 --- [ctor-http-nio-2] reactor.Mono.Just.1 : | onSubscribe([Synchronous Fuseable] Operators.ScalarSubscription)
2018-01-21 17:15:04.764 INFO 8148 --- [ctor-http-nio-2] reactor.Mono.Just.1 : | request(1)
2018-01-21 17:15:04.764 INFO 8148 --- [ctor-http-nio-2] reactor.Mono.Just.1 : | onNext(Hello WebFlux)
2018-01-21 17:15:04.787 INFO 8148 --- [ctor-http-nio-2] reactor.Mono.Just.1 : | request(1)
2018-01-21 17:15:04.787 INFO 8148 --- [ctor-http-nio-2] reactor.Mono.Just.1 : | request(31)
2018-01-21 17:15:04.787 INFO 8148 --- [ctor-http-nio-2] reactor.Mono.Just.1 : | onComplete()
2018-01-21 17:15:05.264 INFO 8148 --- [ctor-http-nio-2] reactor.Mono.Just.1 : | cancel()
■ 예제 2
package toby;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
@SpringBootApplication
@RestController
@Slf4j
public class Toby013Application {
@GetMapping("/")
Mono<String> hello() {
log.info("pos1");
Mono m = Mono.just("Hello WebFlux").log(); // Publisher -> (Publisher) -> (Publisher) -> Subscriber
log.info("pos2");
return m;
}
public static void main(String[] args) {
SpringApplication.run(Toby013Application.class, args);
}
}
<결과>
2018-01-21 17:18:46.265 INFO 13388 --- [ctor-http-nio-2] toby.Toby013Application : pos1
2018-01-21 17:18:46.268 INFO 13388 --- [ctor-http-nio-2] toby.Toby013Application : pos2
2018-01-21 17:18:46.284 INFO 13388 --- [ctor-http-nio-2] reactor.Mono.Just.1 : | onSubscribe([Synchronous Fuseable] Operators.ScalarSubscription)
2018-01-21 17:18:46.285 INFO 13388 --- [ctor-http-nio-2] reactor.Mono.Just.1 : | request(1)
2018-01-21 17:18:46.286 INFO 13388 --- [ctor-http-nio-2] reactor.Mono.Just.1 : | onNext(Hello WebFlux)
2018-01-21 17:18:46.307 INFO 13388 --- [ctor-http-nio-2] reactor.Mono.Just.1 : | request(1)
2018-01-21 17:18:46.308 INFO 13388 --- [ctor-http-nio-2] reactor.Mono.Just.1 : | request(31)
2018-01-21 17:18:46.308 INFO 13388 --- [ctor-http-nio-2] reactor.Mono.Just.1 : | onComplete()
2018-01-21 17:18:46.746 INFO 13388 --- [ctor-http-nio-2] reactor.Mono.Just.1 : | cancel()
■ 예제 3
package toby;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
@SpringBootApplication
@RestController
@Slf4j
public class Toby013Application {
@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(Toby013Application.class, args);
}
}
<결과>
2018-01-21 17:20:50.096 INFO 13748 --- [ctor-http-nio-2] toby.Toby013Application : pos1
2018-01-21 17:20:50.099 INFO 13748 --- [ctor-http-nio-2] toby.Toby013Application : pos2
2018-01-21 17:20:50.115 INFO 13748 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | onSubscribe([Fuseable] FluxPeekFuseable.PeekFuseableSubscriber)
2018-01-21 17:20:50.117 INFO 13748 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | request(1)
2018-01-21 17:20:50.117 INFO 13748 --- [ctor-http-nio-2] toby.Toby013Application : Hello WebFlux
2018-01-21 17:20:50.117 INFO 13748 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | onNext(Hello WebFlux)
2018-01-21 17:20:50.138 INFO 13748 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | request(1)
2018-01-21 17:20:50.138 INFO 13748 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | request(31)
2018-01-21 17:20:50.139 INFO 13748 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | onComplete()
2018-01-21 17:20:50.229 INFO 13748 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | cancel()
■ 예제 4
package toby;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
@SpringBootApplication
@RestController
@Slf4j
public class Toby013Application {
@GetMapping("/")
Mono<String> hello() {
log.info("pos1");
Mono m = Mono.just(generateHello()).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(Toby013Application.class, args);
}
}
<결과>
2018-01-21 17:26:20.531 INFO 14112 --- [ctor-http-nio-2] toby.Toby013Application : pos1
2018-01-21 17:26:20.531 INFO 14112 --- [ctor-http-nio-2] toby.Toby013Application : method generateHello()
2018-01-21 17:26:20.534 INFO 14112 --- [ctor-http-nio-2] toby.Toby013Application : pos2
2018-01-21 17:26:20.552 INFO 14112 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | onSubscribe([Fuseable] FluxPeekFuseable.PeekFuseableSubscriber)
2018-01-21 17:26:20.553 INFO 14112 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | request(1)
2018-01-21 17:26:20.553 INFO 14112 --- [ctor-http-nio-2] toby.Toby013Application : Hello Mono
2018-01-21 17:26:20.553 INFO 14112 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | onNext(Hello Mono)
2018-01-21 17:26:20.575 INFO 14112 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | request(1)
2018-01-21 17:26:20.575 INFO 14112 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | request(31)
2018-01-21 17:26:20.575 INFO 14112 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | onComplete()
2018-01-21 17:26:20.755 INFO 14112 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | cancel()
■ 예제 5
package toby;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
@SpringBootApplication
@RestController
@Slf4j
public class Toby013Application {
@GetMapping("/")
Mono<String> hello() {
log.info("pos1");
Mono m = Mono.fromSupplier(() -> generateHello()).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(Toby013Application.class, args);
}
}
<결과>
2018-01-21 17:29:04.571 INFO 13256 --- [ctor-http-nio-2] toby.Toby013Application : pos1
2018-01-21 17:29:04.575 INFO 13256 --- [ctor-http-nio-2] toby.Toby013Application : pos2
2018-01-21 17:29:04.589 INFO 13256 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | onSubscribe([Fuseable] FluxPeekFuseable.PeekFuseableSubscriber)
2018-01-21 17:29:04.591 INFO 13256 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | request(1)
2018-01-21 17:29:04.591 INFO 13256 --- [ctor-http-nio-2] toby.Toby013Application : method generateHello()
2018-01-21 17:29:04.591 INFO 13256 --- [ctor-http-nio-2] toby.Toby013Application : Hello Mono
2018-01-21 17:29:04.591 INFO 13256 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | onNext(Hello Mono)
2018-01-21 17:29:04.622 INFO 13256 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | request(1)
2018-01-21 17:29:04.622 INFO 13256 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | request(31)
2018-01-21 17:29:04.623 INFO 13256 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | onComplete()
■ 예제 6
package toby;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
@SpringBootApplication
@RestController
@Slf4j
public class Toby013Application {
@GetMapping("/")
Mono<String> hello() {
log.info("pos1");
Mono m = Mono.fromSupplier(() -> generateHello()).doOnNext(c->log.info(c)).log(); // Publisher -> (Publisher) -> (Publisher) -> Subscriber
m.subscribe();
log.info("pos2");
return m;
}
private String generateHello() {
log.info("method generateHello()");
return "Hello Mono";
}
public static void main(String[] args) {
SpringApplication.run(Toby013Application.class, args);
}
}
<결과>
2018-01-21 17:33:30.588 INFO 13316 --- [ctor-http-nio-2] toby.Toby013Application : pos1
2018-01-21 17:33:30.596 INFO 13316 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | onSubscribe([Fuseable] FluxPeekFuseable.PeekFuseableSubscriber)
2018-01-21 17:33:30.598 INFO 13316 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | request(unbounded)
2018-01-21 17:33:30.598 INFO 13316 --- [ctor-http-nio-2] toby.Toby013Application : method generateHello()
2018-01-21 17:33:30.598 INFO 13316 --- [ctor-http-nio-2] toby.Toby013Application : Hello Mono
2018-01-21 17:33:30.598 INFO 13316 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | onNext(Hello Mono)
2018-01-21 17:33:30.599 INFO 13316 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | onComplete()
2018-01-21 17:33:30.599 INFO 13316 --- [ctor-http-nio-2] toby.Toby013Application : pos2
2018-01-21 17:33:30.612 INFO 13316 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | onSubscribe([Fuseable] FluxPeekFuseable.PeekFuseableSubscriber)
2018-01-21 17:33:30.612 INFO 13316 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | request(1)
2018-01-21 17:33:30.612 INFO 13316 --- [ctor-http-nio-2] toby.Toby013Application : method generateHello()
2018-01-21 17:33:30.612 INFO 13316 --- [ctor-http-nio-2] toby.Toby013Application : Hello Mono
2018-01-21 17:33:30.612 INFO 13316 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | onNext(Hello Mono)
2018-01-21 17:33:30.633 INFO 13316 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | request(1)
2018-01-21 17:33:30.633 INFO 13316 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | request(31)
2018-01-21 17:33:30.634 INFO 13316 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | onComplete()
2018-01-21 17:33:31.249 INFO 13316 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | cancel()
■ 예제 7
package toby;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
@SpringBootApplication
@RestController
@Slf4j
public class Toby013Application {
@GetMapping("/")
Mono<String> hello() {
log.info("pos1");
String msg = generateHello();
Mono<String> m = Mono.just(msg).doOnNext(c->log.info(c)).log(); // Publisher -> (Publisher) -> (Publisher) -> Subscriber
String msg2 = m.block();
log.info("pos2: " + msg2);
return m;
}
private String generateHello() {
log.info("method generateHello()");
return "Hello Mono";
}
public static void main(String[] args) {
SpringApplication.run(Toby013Application.class, args);
}
}
<결과>
2018-01-21 17:39:20.356 INFO 11348 --- [ctor-http-nio-2] toby.Toby013Application : pos1
2018-01-21 17:39:20.356 INFO 11348 --- [ctor-http-nio-2] toby.Toby013Application : method generateHello()
2018-01-21 17:39:20.362 INFO 11348 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | onSubscribe([Fuseable] FluxPeekFuseable.PeekFuseableSubscriber)
2018-01-21 17:39:20.364 INFO 11348 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | request(unbounded)
2018-01-21 17:39:20.364 INFO 11348 --- [ctor-http-nio-2] toby.Toby013Application : Hello Mono
2018-01-21 17:39:20.364 INFO 11348 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | onNext(Hello Mono)
2018-01-21 17:39:20.364 INFO 11348 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | onComplete()
2018-01-21 17:39:20.365 INFO 11348 --- [ctor-http-nio-2] toby.Toby013Application : pos2: Hello Mono
2018-01-21 17:39:20.381 INFO 11348 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | onSubscribe([Fuseable] FluxPeekFuseable.PeekFuseableSubscriber)
2018-01-21 17:39:20.381 INFO 11348 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | request(1)
2018-01-21 17:39:20.381 INFO 11348 --- [ctor-http-nio-2] toby.Toby013Application : Hello Mono
2018-01-21 17:39:20.381 INFO 11348 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | onNext(Hello Mono)
2018-01-21 17:39:20.407 INFO 11348 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | request(1)
2018-01-21 17:39:20.407 INFO 11348 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | request(31)
2018-01-21 17:39:20.407 INFO 11348 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | onComplete()
2018-01-21 17:39:20.579 INFO 11348 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | cancel()
- block : publisher가 제공하는 결과값을 꺼내서 Mono나 Flux 같은 컨테이너를 제거하고 값을 넘겨주는 것이 목적.
■ 예제 8
package toby;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
@SpringBootApplication
@RestController
@Slf4j
public class Toby013Application {
@GetMapping("/")
Mono<String> hello() {
log.info("pos1");
String msg = generateHello();
Mono<String> m = Mono.just(msg).doOnNext(c->log.info(c)).log(); // Publisher -> (Publisher) -> (Publisher) -> Subscriber
String msg2 = m.block();
log.info("pos2: " + msg2);
return Mono.just(msg2);
}
private String generateHello() {
log.info("method generateHello()");
return "Hello Mono";
}
public static void main(String[] args) {
SpringApplication.run(Toby013Application.class, args);
}
}
<결과>
2018-01-21 17:48:23.009 INFO 13012 --- [ctor-http-nio-2] toby.Toby013Application : pos1
2018-01-21 17:48:23.009 INFO 13012 --- [ctor-http-nio-2] toby.Toby013Application : method generateHello()
2018-01-21 17:48:23.015 INFO 13012 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | onSubscribe([Fuseable] FluxPeekFuseable.PeekFuseableSubscriber)
2018-01-21 17:48:23.016 INFO 13012 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | request(unbounded)
2018-01-21 17:48:23.016 INFO 13012 --- [ctor-http-nio-2] toby.Toby013Application : Hello Mono
2018-01-21 17:48:23.017 INFO 13012 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | onNext(Hello Mono)
2018-01-21 17:48:23.017 INFO 13012 --- [ctor-http-nio-2] reactor.Mono.PeekFuseable.1 : | onComplete()
2018-01-21 17:48:23.018 INFO 13012 --- [ctor-http-nio-2] toby.Toby013Application : pos2: Hello Mono
'IT > Spring Framework' 카테고리의 다른 글
서블릿(Servlet)과 JSP(Java Sever Pages) (0) | 2018.02.14 |
---|---|
토비의 봄 TV 14회 스프링 리액티브 프로그래밍 (10) Flux의 특징과 활용방법 (0) | 2018.02.04 |
토비의 봄 TV 12회 스프링 리액티브 프로그래밍 (8) WebFlux (0) | 2018.02.03 |
토비의 봄 TV 11회 스프링 리액티브 프로그래밍 (7) CompletableFuture (0) | 2018.02.03 |
토비의 봄 TV 10회 스프링 리액티브 프로그래밍 (6) AsyncRestTemplate의 콜백 헬과 중복 작업 문제 (0) | 2018.02.03 |
@DEAN :: Dean Story
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!