最后编写启动入口类:
package com.github.jojotech.spring.cloud.apigateway; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication(scanBasePackages = "com.github.jojotech.spring.cloud.apigateway") public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }启动,访问路径: :8181/test-ss/anything,可以看到请求被发送到 httpbin.org 的 anything 路径中,这个接口会返回请求中的所有信息。
这样,我们就实现了一个简单的网关。接下来我们来详细分析其工作流程和源码。
异步环境下请求处理的核心 - Spring Boot + Spring WebFlux 的 WebHandler我们创建的简易网关,外层的服务容器其实就是基于 Netty 和 Project Reactor 的容器,我们跳过这些,直接进入 Spring Boot 相关的处理逻辑。我们只需要知道,请求和其对应的响应,会被外层的容器封装成为 ServerHttpRequest request 和 ServerHttpResponse response(都在 org.springframework.http.server.reactive 这个包下)。
然后,会交由 WebHandler 进行处理。WebHandler 的实现,其实是一种责任链装饰模式,如下图所示。每一层的 WebHandler 会将 request 和 response 进行对应自己责任的装饰,然后交给内层的 WebHandler 处理。
HttpWebHandlerAdapter - 将请求封装成 ServerWebExchangeWebHandler 的接口定义是:
public interface WebHandler { Mono<Void> handle(ServerWebExchange exchange); }但是最外层传进来的参数是 request 和 response,需要将他们封装成 ServerWebExchange,这个工作就是在 HttpWebHandlerAdapter 中做的。HttpWebHandlerAdapter 其实主要任务就是将各种参数封装成 ServerWebExchange(除了和本次请求相关的 request 和 response,还有会话管理器 SessionManager,编码解码器配置,国际化配置还有 ApplicationContext 用于扩展)。
除了这些,处理 Forwarded 还有 X-Forwarded* 相关的 Header 的配置逻辑,也在这里进行。然后将封装好的 ServerWebExchange 交给内层的 WebHandler 即 ExceptionHandlingWebHandler 继续处理。同时,从源码中可以看出,交给内层处理的 Mono 还加入了异常处理和记录响应信息的逻辑:
HttpWebHandlerAdapter.java
//交给内层处理封装好的 `ServerWebExchange` return getDelegate().handle(exchange) //记录响应日志,trace 级别,一般用不上 .doOnSuccess(aVoid -> logResponse(exchange)) //处理内层没有处理的异常,一般不会走到这里 .onErrorResume(ex -> handleUnresolvedError(exchange, ex)) //在所有处理完成后,将 response 设为 complete .then(Mono.defer(response::setComplete));剩下的内层的 WebHandler,我们将在下一节中继续分析
微信搜索“我的编程喵”关注公众号,每日一刷,轻松提升技术,斩获各种offer: