본문 바로가기

Java

Spring Webflux 간단하게 알아보기

Webflux 란?

 

WebFlux는 스프링 5에서 소개된 리액티브 프로그래밍을 지원하는 모듈입니다. 리액티브 프로그래밍은 비동기 및 이벤트 기반 애플리케이션을 개발하기 위한 패러다임으로, 주로 높은 확장성과 성능을 위해 사용됩니다.

 

Spring Webflux Single-Thread Non-Blocking 방식을 사용합니다.

 


 

주요특징

 

webflux 의 주요 특징중 하나는 리액티브 프로그래밍입니다.

 

WebFlux는 리액티브 프로그래밍 모델을 채택하고 있습니다.

이 모델은 비동기적이며 이벤트 기반으로 동작하여 높은 확장성과 성능을 제공합니다.

 

기존의 Blocking 형식의 리퀘스트는 서버에 리퀘스트가 전송될 때 마다, 서블릿 스레드가 생성되고, 워커(worker) 스레드에 작업을 위임한다.

워커 스레드가 처리를 하는동안 서블릿 스레드는 응답을 기다린다.

 

 

하지만 Non-Blockiing 리퀘스트의 경우 이벤트 핸들러와 콜백을 모든 요청에 포함한다. 요청 스레드는 스레드풀에 요청을 위임하고 다음 요청을 처리하는데 바로 사용될 수 있다. 핸들러 함수를 통해 요청이 완료되면 콜백함수에 전달한다.

 

 

추가적인 특징으로는 아래와 같습니다.

 

  • Reactor 라이브러리: WebFlux는 Reactor 라이브러리를 사용하여 리액티브 프로그래밍을 지원합니다. Reactor는 Publisher-Subscriber 패턴과 함께 Flux(0 또는 여러 개의 이벤트를 발생시키는 데이터 스트림)와 Mono(0 또는 1개의 이벤트를 발생시키는 데이터 스트림) 등의 개념을 제공합니다.

 

  • 함수형 엔드포인트: WebFlux는 기존의 컨트롤러 대신 함수형 엔드포인트를 도입했습니다. 이를 통해 간결하고 강력한 람다 표현식을 사용하여 엔드포인트를 정의할 수 있습니다.

 

  • 백프레셔너블(Backpressure): 리액티브 시스템에서 발생하는 데이터 흐름의 속도를 제어하기 위해 백프레셔너블을 지원합니다. 이를 통해 소비자가 생산자로부터의 데이터 흐름을 제어할 수 있습니다.

 

  • 논블로킹 I/O: WebFlux는 논블로킹 I/O를 사용하여 요청을 비동기적으로 처리하므로 스레드 풀을 효율적으로 활용하고 높은 동시성을 지원합니다.

 

  • 양방향 코드 구성: WebFlux는 동일한 코드로 서버 및 클라이언트 사이에서 리액티브한 통신을 할 수 있도록 지원합니다.

간단한 예제를 통해 webflux 사용해보기

 

버전

  • Java 1.8 or later
  • Gradel 7.5+ or Maven 3.5+

 

이브러리 등록

  1. start spring io 를 통해 라이브러리 등록 

 

 

 

 2.  gradle 을 통해 라이브러리 등록

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

 

 

 3.  maven 을 통해 라이브러리 등록

<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
  </dependency>
 </dependencies>

 

WebFlux Handler 생성

 

RESTful 서비스에 의해 JSON으로 직렬화될 Greeting POJO부터 생성하겠습니다.

 

public class Greeting {

    private String message;

    public Greeting() {
    }

    public Greeting(String message) {
        this.message = message;
    }

    public String getMessage() {
        return this.message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    @Override
    public String toString() {
        return "Greeting{" +
                "message='" + message + '\'' +
                '}';
    }
}

 

 

Spring Reactive 접근 방식에서는 아래와 같이 핸들러를 사용하여 요청을 처리하고 응답을 생성합니다.

 

핸들러 이외에도 controller도  제공하는데 다음에 다루어 보도록 하겠습니다.

 

import com.example.demo.pojo.Greeting;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;

@Component
public class GreetingHandler {
    public Mono<ServerResponse> hello(ServerRequest request) {
        return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON)
                .body(BodyInserters.fromValue(new Greeting("Hello, Spring!")));
    }
}

 

이 간단한 반응형 클래스는 항상 "Hello, Spring!"과 함께 JSON 본문을 반환합니다.

데이버베이스나 다른 서비스 로직에 의해 생성된 스트림을 포함하여 다른 항목으로 반환할 수 있습니다.

 

ServerResponse 본문을 보유하는 Mono 객체가 중요합니다.

 

 

Router 생성

 

WebFlux 는 아래와 같이 Router 를 사용하여 경로(/hello)를 처리합니다.

 

import com.example.demo.handler.GreetingHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;

import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
import static org.springframework.web.reactive.function.server.RequestPredicates.accept;

@Configuration(proxyBeanMethods = false)
public class GreetingRouter {

    @Bean
    public RouterFunction<ServerResponse> route(GreetingHandler greetingHandler) {

        return RouterFunctions
                .route(GET("/hello").and(accept(MediaType.APPLICATION_JSON)), greetingHandler::hello);
    }
}

 


Postman 으로 애플리케이션 테스트

 

아래와 같이 잘 반환되는것을 보실 수 있습니다.

 


참조 

https://spring.io/guides/gs/reactive-rest-service/