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 으로 애플리케이션 테스트
아래와 같이 잘 반환되는것을 보실 수 있습니다.
참조
'Java' 카테고리의 다른 글
[Spring] variable not initialized in the default constructor 에러 (0) | 2024.01.11 |
---|---|
[Java] Reactive Streams 란? (1) | 2024.01.10 |
[Java] SHA-256 암호화 & Salt ( 적용예시 ) (1) | 2023.05.17 |
[Java] ArrayList 정렬 / Collections, List, 사용자정의 (0) | 2023.05.07 |
[java] :: 더블콜론의 의미 (0) | 2023.03.28 |