Spring

[Spring Webflux] 리액티브 프로그래밍 구조 / 사용 용어

jungha_k 2022. 11. 29. 15:29

명령형 프로그래밍 vs 선언형 프로그래밍

: 명령형 프로그래밍 = 무엇을 '어떻게' 할 것인가

선언형 프로그래밍 = '무엇을' 할 것인가

 

* 리액티브 프로그래밍의 대표적 특징 = 선언형 프로그래밍 방식 사용!

 

 

명령형 프로그래밍

public class ImperativeProgrammingExample {
    public static void main(String[] args){
        // List에 있는 숫자들 중에서 4보다 큰 짝수의 합계 구하기
        List<Integer> numbers = List.of(1, 3, 6, 7, 8, 11);
        int sum = 0;

        for(int number : numbers){
            if(number > 4 && (number % 2 == 0)){
                sum += number;
            }
        }

        System.out.println(sum);
    }
}

코드가 실행되어야 하는 구체적 로직들이 코드 안에 그대로 드러남

코드 위➡아래 로 순차적 실행

 

 

✨ 선언형 프로그래밍

public class DeclarativeProgramingExample {
    public static void main(String[] args){
        // List에 있는 숫자들 중에서 4보다 큰 짝수의 합계 구하기
        List<Integer> numbers = List.of(1, 3, 6, 7, 8, 11);

        int sum =
                numbers.stream()
                        .filter(number -> number > 4 && (number % 2 == 0))
                        .mapToInt(number -> number)
                        .sum();

        System.out.println("# 선언형 프로그래밍: " + sum);
    }
}

: 하나부터 열까지 개발자가 일일히 로직 작성 X

필요한 동작들을 람다 표현식으로 정의

구체적인 동작 수행 ➡ Operation(연산) 메서드 체인에 위임

 

* Stream : 최종 연산 수행하는 메서드 호출하지 않으면, 메서드 체인들이 실행되지 않음

 우선 람다 표현식(작업 요청 선언)만 넘겨주고, 최종 연산 호출 될때 동작을 수행함

 


리액티브 프로그래밍의 기본 구조

import reactor.core.publisher.Mono;

// 리액티브 프로그래밍 기본 구조
public class HelloReactiveExample01 {
    public static void main(String[] args) {
        // ✨ Publisher의 역할 : 데이터 emit
        Mono<String> mono = Mono.just("Hello, Reactive");

        // ✨ Subscriber의 역할 : emit한 데이터 전달받아 소비
        mono.subscribe(message -> System.out.println(message));
    }
}

 

 

⬇ 메서드 체인 형태로 표현 ⬇

 

import reactor.core.publisher.Mono;

// 리액티브 프로그래밍 기본 구조
public class HelloReactiveExample02 {
    public static void main(String[] args) {
        Mono
            .just("Hello, Reactive")
            .subscribe(message -> System.out.println(message));
    }
}

* Stream API != 리액티브 프로그래밍

 

 


import reactor.core.publisher.Flux;

import java.util.List;

public class ReactiveGlossaryExample {
    public static void main(String[] args) {
        Flux
            .fromIterable(List.of(1, 3, 6, 7, 8, 11))
            .filter(number -> number > 4 && (number % 2 == 0))
            .reduce((n1, n2) -> n1 + n2)
            .subscribe(System.out::println); //Subscriber

    }
}

 

리액티브 프로그래밍 사용 용어

 

  • Publisher : 데이터를 내보내는 주체
    ex) Mono, Flux 
    * 차이점? 발행하는 데이터 갯수가 다르다 - Flux(0 ~ N) / Mono(0 ~ 1)

  • Emit : Publisher 가 데이터를 내보내는 것

  • Subscriber : Publisher가 emit 한 데이터를 전달받아 소비하는 주체

  • Subscribe : 구독

  • Signal : Publisher 가 발생시키는 이벤트 (= 데이터 변경되는 그 자체)

  • Operator : 어떤 동작을 수행하는 메서드(=연산자)
    ex) fromIterable(), filter(), reduce()

  • Sequence : Operator 체인으로 표현되는 데이터의 흐름

  • Upstream / Downstream : 특정 Operator 기준,
    Upstream = 한 Sequence의 위쪽
    Downstream = 한 Sequence의 아래쪽