스프링의 변천사 그리고 Java 9 과 Spring 5 (3)
3. 새로운 변화
새로운 위기 : 애노테이션과 메타프로그래밍 관례의 범람.
애노테이션은 컴파일러에 검증되지 않고 코드 행위를 규정하지 않는다.
규칙이나 표준이 없어 이해하기 어렵고 오해하기 쉽다. 그리고 테스트가 안된다.
@Controller
@RequestMaping("/path")
public class MyController extends SuperController implements MyInterface {
// home() 은 어떤 url 에 매핑되나?
@RequestMapping("/home")
public String home() { return "home" }
}
@RequestMapping("/super")
public class SuperController { }
@RequestMapping("/if")
interface MyInterface extends SuperInterface { }
@RequestMapping("/superif")
interface SuperInterface { }
3-1. 스프링 5.0
-
새로운 함수형 스타일 웹 개발 지원.
-
서블릿의 의존성 제거해 서블릿 컨테이너가 없어도 스프링 5 를 지원하는 자바로 만든 HTTP 서버라면
스프링 5 애플리케이션을 띄울 수 있다. -
새로운 HTTP 요청과 응답의 추상화 - 불변 객체 ServerRequest, ServerResponse
-
두 개의 함수를 이용해 개발 - HandlerFunction, RouterFunction
-
Mono
, Flux 와 같은 리액티브 방식으로 개발
3-1-1. 스프링의 요청 처리
기존 웹 핸들러(컨트롤러) 가 웹 요청을 처리하는 방식
요청 매핑 → 요청 바인딩 → 핸들러 실행 → 핸들러 결과 처리
기존 방법
@RestController
public class MyController {
@GetMapping("/hello/{name}")
String hello(@PathVariable String name) {
return "Hello " + name;
}
}
RouterFunction, HandlerFunction 을 이용
@FunctionalInterface
public interface HandlerFunction<T extends ServerResponse> {
Mono<T> handle(ServerRequest request);
}
@FunctionalInterface
public interface RouterFunction<T extends ServerResponse> {
Mono<HandlerFuncion<T>> route(ServerRequest request);
}
public static void main(String[] args) throws Exception {
HandlerFunction helloHandler = (ServerRequest req) -> {
String name = req.pathVariable("name");
return ServerResponse.ok().syncBody("Hello " + name);
}
RouterFunction router = req -> RequestPredicates.path("/hello/{name}").test(req) ?
Mono.just(helloHandler) : Mono.empty();
HttpHandler httpHandler = RouterFunctions.toHttpHandler(router);
// Netty HTTP 서버 구동
ReactorHttpHandlerAdapter adapter = new ReactorHttpHandlerAdapter(httpHandler);
HttpServer server = HttpServer.create("localhost", 8080);
server.newHandler(adapter).block();
System.in.read();
}
3-1-2. Mono/Flux
정보를 컨테이너에 담아서 전달한다. 피보탈에서 만든 ProjectReactor 에서 제공하고
Mono 는 단일 오브젝트, Flux 는 스트림 오브젝트 형식이다.
스프링 5 는 리액티브 프로그래밍 스타일로 스프링을 개발할 수 있도록 준비되어 있다.
ReactiveStreams 표준 API 를 지원하는 RxJava2 또는 ProjectReactor 를 사용할 수 있다.
함수형 스타일의 비동기 논블로킹 방식으로 동작하는 고성능 코드이다.
3-2. 자바 9
자바 9 에 Flow API 가 추가되었다. Flow API 는 ReactiveStreams 표준과 호환된다.
따라서 스프링의 Mono/Flux 와 Flow API 를 함께 사용해서 개발할 수 있다.