반응형

이전 글: 2022.03.21 - [분류 전체보기] - [reactive] 7. CompletableFuture

 

[reactive] 7. CompletableFuture

이전 글: 2022.03.21 - [개발/reactive] - [reactive] 6. refactoring [reactive] 6. refactoring 이전 글: 2022.03.18 - [개발/reactive] - [reactive] 5. 비동기 RestTemplate과 비동기 MVC/Servlet [reactive..

bangpurin.tistory.com

 

 

저번 시간에 작성한 application을 webflux로 바꿔보는 작업을 진행한다.

springboot2.6.4로 진행하였기 때문에 유튜브와 다르게 아래의 의존성을 추가했다. 

implementation 'org.springframework.boot:spring-boot-starter:2.6.4'
//   implementation 'org.springframework.boot:spring-boot-starter-web:2.6.4'
implementation "org.springframework.boot:spring-boot-starter-webflux:2.6.4"

spring-webflux는 기본 서버가 netty라서 모두 네티로 작업하였다.

그리고 설정명이 달라서 수정하였다. 아래 소스를 참고!

@Slf4j
@EnableAsync
@SpringBootApplication
public class Application {

    @RestController
    public static class MyController{

        @Autowired
        MyService myService;

        WebClient client = WebClient.create();

        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) {
            //이것만으로는 api 쏘지 않음
            Mono<ClientResponse> r = client.get()
                    .uri(URL1, idx)
                    .exchange();
            //container안의 원소를 받아서 변환해서 다시 container(모노) 담아서 리턴 Mono<Mono<String>>
            //이중으로 감싸주는 것은 원하는 결과가 아니니 flatmap으로 작업해서 하나로 합쳐야 함
            Mono<String> body = r
                    .flatMap(clientResponse -> clientResponse.bodyToMono(String.class))  //Mono<String>
                    .doOnNext(c -> log.info(c))
                    .flatMap(res1 -> client.get().uri(URL2, res1).exchange())            //Mono<ClientResponse>
                    .flatMap(c -> c.bodyToMono(String.class))                            //Mono<String>
                    .doOnNext(c -> log.info(c))
                    .flatMap(res2 -> Mono.fromCompletionStage(myService.work(res2)))     //completable<String> -> mono<String>
                    .doOnNext(c -> log.info(c))
                    ;

            //return 시 모노면 그때 subscribe 수행함
            //mono subscribe 를 spring이 실행해줌
            return body;
        }

    }

    @Service
    public static class MyService{
        //또다른 스래드 비동기 작업 시 async
        @Async
        public CompletableFuture<String> work(String req){
            return CompletableFuture.completedFuture(req + "/asyncwork");
        }
    }

    public static void main(String[] args) {
        System.setProperty("reactor.netty.ioWorkerCount", "1");
        System.setProperty("reactor.netty.pool.maxConnections", "2000");
        SpringApplication.run(Application.class, args);
    }
}

참고로 위 코드는 아래 코드를 수정한 것이다.

소스를 살펴보면 mono의 map과 flatmap의 사용 차이를 느낄 수 있을 것이다.

@GetMapping("/rest")
public Mono<String> rest(int idx) {
    Mono<ClientResponse> r = client.get()
            .uri(URL1, idx)
            .exchange();

    Mono<String> body = r
            .flatMap(clientResponse -> clientResponse.bodyToMono(String.class))  //Mono<String>
            .flatMap(res1 -> client.get().uri(URL2, res1).exchange())            //Mono<ClientResponse>
            .flatMap(c -> c.bodyToMono(String.class))                            //Mono<String>
            .map(res2 -> myService.work(res2))
            ;

    return body;
}
////////////////////////

@Service
public static class MyService{
    public String work(String req){
        log.info("myservice {}" , req);
        return req + "/asyncwork";
    }
}

 

map과 flatmap의 차이는 아래 링크에서 자세히 확인 가능하다. 스트림으로서의 차이는 이해했는데 동기/비동기에 대해서는 아직 잘 모르겠다.

https://www.geeksforgeeks.org/difference-between-map-and-flatmap-in-java-stream/

 

Difference Between map() And flatMap() In Java Stream - GeeksforGeeks

A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.

www.geeksforgeeks.org

https://luvstudy.tistory.com/95

 

Reactor map, flatMap method는 언제 써야할까?

webflux로 서비스를 만들어보면서 map과 flatMap을 언제 써야 할지 헷갈릴 때가 있어 공부한 내용을 정리함. map과 flatMap은 둘 다 스트림의 중간에 값을 변환해주는 역할을 한다. map은 1 : 1로 반환을 보

luvstudy.tistory.com

 

728x90
반응형

'개발 > reactive' 카테고리의 다른 글

[reactive] 10. Flux  (0) 2022.03.25
[reactive] 9. Mono  (0) 2022.03.23
[reactive] 7. CompletableFuture  (0) 2022.03.21
[reactive] 6. refactoring  (0) 2022.03.21
[reactive] 5. 비동기 RestTemplate과 비동기 MVC/Servlet  (0) 2022.03.18

+ Recent posts