Java Flux contains_Spring WebFlux启动源码分析

本文详细分析了Spring Boot中WebFlux的启动流程,从`createWebServer()`方法开始,讲解了如何创建`WebServerManager`,接着探讨了`NettyWebServer`的创建过程,包括`HttpServer`、`TcpServer`的创建和配置。通过源码跟踪,揭示了`HttpServer`的启动步骤,涉及到`bind()`和`block()`方法的调用,以及Netty相关的配置。文章深入浅出地剖析了Spring WebFlux启动背后的机制和设计思路。
摘要由CSDN通过智能技术生成

0 核心类

NettyWebServer

HttpServer

HttpHandler

TcpServer

1 创建 WebServer

根据之前的文章 《Spring Boot启动源码分析》可知,当执行 AbstractApplicationContext -> onRefresh()方法时,如果引入了 webflux 相关依赖,会创建 WebServer。

/** ReactiveWebServerApplicationContext **/

private void createWebServer() {

WebServerManager serverManager = this.serverManager;

if (serverManager == null) {

String webServerFactoryBeanName = getWebServerFactoryBeanName(); // 1.1

ReactiveWebServerFactory webServerFactory = getWebServerFactory(webServerFactoryBeanName); // 1.1

boolean lazyInit = getBeanFactory().getBeanDefinition(webServerFactoryBeanName).isLazyInit();

this.serverManager = new WebServerManager(this, webServerFactory, this::getHttpHandler, lazyInit); // 1.2

getBeanFactory().registerSingleton("webServerGracefulShutdown",

new WebServerGracefulShutdownLifecycle(this.serverManager));

getBeanFactory().registerSingleton("webServerStartStop",

new WebServerStartStopLifecycle(this.serverManager)); // 1.3

}

initPropertySources();

}

复制代码

1.1、根据 web 容器类型,选择对应的ReactiveWebServerFactory。比如我这里是默认的 Netty,那么webServerFactory就是NettyReactiveWebServerFactory 类型。

1.2、创建WebServerManager对象,用来管理 Server 以及 HttpHandler,入参ReactiveWebServerFactory和HttpHandler都从 bean 容器中获取。

1.3、注册WebServerStartStopLifecycle bean,负责 Server 的启动和停止。

Q:Server 何时启动?

A:SpringApplication -> refresh(ConfigurableApplicationContext applicationContext)方法,调用AbstractApplicationContext -> finishRefresh(),之后调用DefaultLifecycleProcessor -> onRefresh(),之后调用 DefaultLifecycleProcessor -> doStart(Map lifecycleBeans, String beanName, boolean autoStartupOnly),最终调用 1.3 中的WebServerStartStopLifecycle -> start() 方法,启动服务。

接下来看下WebServerManager类,

class WebServerManager {

private final ReactiveWebServerApplicationContext applicationContext;

private final DelayedInitializationHttpHandler handler;

private final WebServer webServer;

WebServerManager(ReactiveWebServerApplicationContext applicationContext, ReactiveWebServerFactory factory,

Supplier handlerSupplier, boolean lazyInit) {

this.applicationContext = applicationContext;

Assert.notNull(factory, "Factory must not be null");

this.handler = new DelayedInitializationHttpHandler(handlerSupplier, lazyInit);

this.webServer = factory.getWebServer(this.handler); // 1.4

}

void start() {

this.handler.initializeHandler();

this.webServer.start(); // 启动 webServer

this.applicationContext

.publishEvent(new ReactiveWebServerInitializedEvent(this.webServer, this.applicationContext));

}

...

}

复制代码

1.4、创建 webServer,这里会返回NettyWebServer,方法如下:

/** NettyReactiveWebServerFactory **/

public WebServer getWebServer(HttpHandler httpHandler) {

HttpServer httpServer = createHttpServer(); // 1.5

ReactorHttpHandlerAdapter handlerAdapter = new ReactorHttpHandlerAdapter(httpHandler);

NettyWebServer webServer = new NettyWebServer(httpServer, handlerAdapter, this.lifecycleTimeout, getShutdown());

webServer.setRouteProviders(this.routeProviders);

return webServer;

}

private HttpServer createHttpServer() {

HttpServer server = HttpServer.create(); // 1.6 返回HttpServerBind

if (this.resourceFactory != null) { // 1.7 ReactorResourceFactory是bean

LoopResources resources = this.resourceFactory.getLoopResources();

Assert.notNull(resources, "No LoopResources: is ReactorResourceFactory not initialized yet?");

server = server

.tcpConfiguration((tcpServer) -> tcpServer.runOn(resources).bindAddress(this::getListenAddress)); // 1.8 这里返回HttpServerTcpConfig对象

}

else {

server = server.tcpConfiguration((tcpServer) -> tcpServer.bindAddress(this::getListenAddress));

}

if (getSsl() != null && getSsl().isEnabled()) {

SslServerCustomizer sslServerCustomizer = new SslServerCustomizer(getSsl(), getHttp2(),

getSslStoreProvider());

server = sslServerCustomizer.apply(server);

}

if (getCompression() != null && getCompression().getEnabled()) {

CompressionCustomizer compressionCustomizer = new CompressionCustomizer(getCompression());

server = compressionCustomizer.apply(server);

}

server = server.protocol(listProtocols()).forwarded(this.useForwardHeaders); //1.9 这里返回新的HttpServerTcpConfig对象

return applyCustomizers(server); //1.10 这里返回新的HttpServerTcpConfig对象

}

复制代码

1.5、创建HttpServer,底层是TcpServer,后面分析。

1.7、这里提前创建了NettyReactiveWebServerFactory bean。其中LoopResources负责管理线程,ConnectionP

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值