Spring boot加载REACTIVE源码分析
一,加载REACTIVE相关自动配置
private WebApplicationType deduceWebApplicationType() { if (ClassUtils.isPresent("org.springframework.web.reactive.DispatcherHandler", (ClassLoader)null) && !ClassUtils.isPresent("org.springframework.web.servlet.DispatcherServlet", (ClassLoader)null) && !ClassUtils.isPresent("org.glassfish.jersey.server.ResourceConfig", (ClassLoader)null)) { return WebApplicationType.REACTIVE; } else { String[] var1 = WEB_ENVIRONMENT_CLASSES; int var2 = var1.length; for(int var3 = 0; var3 < var2; ++var3) { String className = var1[var3]; if (!ClassUtils.isPresent(className, (ClassLoader)null)) { return WebApplicationType.NONE; } } return WebApplicationType.SERVLET; } }
当程序类型是REACTIVE,spring boot首先就会加载自身的自动配置类org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration。如果找到HttpServer.clas而且又没有自己实现的ReactiveWebServerFactory.class就应用spring boot自带的nettyReactiveWebServerFactory对象。如果会用jetty或tomcat就引用有Server.class或Tomcat.class第三方包。
@AutoConfigureOrder(-2147483648) @Configuration @ConditionalOnClass({ReactiveHttpInputMessage.class}) @ConditionalOnWebApplication( type = Type.REACTIVE ) @EnableConfigurationProperties({ServerProperties.class}) @Import({ReactiveWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class, EmbeddedTomcat.class, EmbeddedJetty.class, EmbeddedUndertow.class, EmbeddedNetty.class}) public class ReactiveWebServerFactoryAutoConfiguration { public ReactiveWebServerFactoryAutoConfiguration() { } ...................................... abstract class ReactiveWebServerFactoryConfiguration { ReactiveWebServerFactoryConfiguration() { } @Configuration @ConditionalOnMissingBean({ReactiveWebServerFactory.class}) @ConditionalOnClass({HttpServer.class}) static class EmbeddedNetty { EmbeddedNetty() { } @Bean public NettyReactiveWebServerFactory nettyReactiveWebServerFactory() { return new NettyReactiveWebServerFactory(); } }
应用程序没有提供WebFluxConfigurationSupport的实例,spring boot就会加载自身的自动配置类org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration。加载对象有webHandler(org.springframework.web.reactive.DispatcherHandler)等
@Configuration @ConditionalOnWebApplication( type = Type.REACTIVE ) @ConditionalOnClass({WebFluxConfigurer.class}) @ConditionalOnMissingBean({WebFluxConfigurationSupport.class}) @AutoConfigureAfter({ReactiveWebServerFactoryAutoConfiguration.class, CodecsAutoConfiguration.class, ValidationAutoConfiguration.class}) @AutoConfigureOrder(-2147483638) public class WebFluxAutoConfiguration {
应用程序没有提供HttpHandler的实例,spring boot就会加载自身的自动配置类org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration,加载对象httpHandler(org.springframework.web.server.adapter.HttpWebHandlerAdapter)。
@Configuration @ConditionalOnClass({DispatcherHandler.class, HttpHandler.class}) @ConditionalOnWebApplication( type = Type.REACTIVE ) @ConditionalOnMissingBean({HttpHandler.class}) @AutoConfigureAfter({WebFluxAutoConfiguration.class}) @AutoConfigureOrder(-2147483638) public class HttpHandlerAutoConfiguration { public HttpHandlerAutoConfiguration() { } @Configuration public static class AnnotationConfig { private ApplicationContext applicationContext; public AnnotationConfig(ApplicationContext applicationContext) { this.applicationContext = applicationContext; } @Bean public HttpHandler httpHandler() { return WebHttpHandlerBuilder.applicationContext(this.applicationContext).build(); } } }
二,创建REACTIVE内嵌服务器
WebServer在org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext创建。依赖的HttpHandler实例上面已说明如果创建的。
org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext protected void onRefresh() { super.onRefresh(); try { this.createWebServer(); } catch (Throwable var2) { throw new ApplicationContextException("Unable to start reactive web server", var2); } } private void createWebServer() { WebServer localServer = this.webServer; if (localServer == null) { this.webServer = this.getWebServerFactory().getWebServer(this.getHttpHandler()); } this.initPropertySources(); }
org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory public WebServer getWebServer(HttpHandler httpHandler) { HttpServer httpServer = this.createHttpServer(); ReactorHttpHandlerAdapter handlerAdapter = new ReactorHttpHandlerAdapter(httpHandler); return new NettyWebServer(httpServer, handlerAdapter, this.lifecycleTimeout); }
三,Annotated Controllers与Functional Endpoints
spring webflux处理http请求有两种编程模式,分别是annotated controllers和functional endpoints,annotated controllers与spring mvc类似。它们都调用HttpHandler实现org.springframework.web.server.adapter.HttpWebHandlerAdapter的handle方法。
handle:183, HttpWebHandlerAdapter (org.springframework.web.server.adapter) apply:75, ReactorHttpHandlerAdapter (org.springframework.http.server.reactive) apply:40, ReactorHttpHandlerAdapter (org.springframework.http.server.reactive) applyHandler:380, ChannelOperations (reactor.ipc.netty.channel) onHandlerStart:407, HttpServerOperations (reactor.ipc.netty.http.server) run:-1, 1927250759 (reactor.ipc.netty.channel.ContextHandler$$Lambda$524) safeExecute$$$capture:163, AbstractEventExecutor (io.netty.util.concurrent) safeExecute:-1, AbstractEventExecutor (io.netty.util.concurrent) - Async stack trace addTask:-1, SingleThreadEventExecutor (io.netty.util.concurrent) execute:765, SingleThreadEventExecutor (io.netty.util.concurrent) createOperations:249, ContextHandler (reactor.ipc.netty.channel) channelRead:136, HttpServerHandler (reactor.ipc.netty.http.server) invokeChannelRead:362, AbstractChannelHandlerContext (io.netty.channel) invokeChannelRead:348, AbstractChannelHandlerContext (io.netty.channel) fireChannelRead:340, AbstractChannelHandlerContext (io.netty.channel) fireChannelRead:438, CombinedChannelDuplexHandler$DelegatingChannelHandlerContext (io.netty.channel) fireChannelRead:310, ByteToMessageDecoder (io.netty.handler.codec) channelRead:284, ByteToMessageDecoder (io.netty.handler.codec) channelRead:253, CombinedChannelDuplexHandler (io.netty.channel) invokeChannelRead:362, AbstractChannelHandlerContext (io.netty.channel) invokeChannelRead:348, AbstractChannelHandlerContext (io.netty.channel) fireChannelRead:340, AbstractChannelHandlerContext (io.netty.channel) channelRead:1434, DefaultChannelPipeline$HeadContext (io.netty.channel) invokeChannelRead:362, AbstractChannelHandlerContext (io.netty.channel) invokeChannelRead:348, AbstractChannelHandlerContext (io.netty.channel) fireChannelRead:965, DefaultChannelPipeline (io.netty.channel) read:163, AbstractNioByteChannel$NioByteUnsafe (io.netty.channel.nio) processSelectedKey:628, NioEventLoop (io.netty.channel.nio) processSelectedKeysOptimized:563, NioEventLoop (io.netty.channel.nio) processSelectedKeys:480, NioEventLoop (io.netty.channel.nio) run:442, NioEventLoop (io.netty.channel.nio) run:884, SingleThreadEventExecutor$5 (io.netty.util.concurrent) run:745, Thread (java.lang)
他们也调用handle:149, DispatcherHandler (org.springframework.web.reactive),但最后他们分别调用BookController或BookHandler,看下面不同调用栈:
annotated controllers getBookById:19, BookController (com.javaworld.webflux.bookservice.web) invoke0:-1, NativeMethodAccessorImpl (sun.reflect) invoke:62, NativeMethodAccessorImpl (sun.reflect) invoke:43, DelegatingMethodAccessorImpl (sun.reflect) invoke:498, Method (java.lang.reflect) doInvoke:243, InvocableHandlerMethod (org.springframework.web.reactive.result.method) lambda$invoke$0:138, InvocableHandlerMethod (org.springframework.web.reactive.result.method) apply:-1, 595198211 (org.springframework.web.reactive.result.method.InvocableHandlerMethod$$Lambda$652) onNext:118, MonoFlatMap$FlatMapMain (reactor.core.publisher) complete:1083, Operators$MonoSubscriber (reactor.core.publisher) signal:247, MonoZip$ZipCoordinator (reactor.core.publisher) .................................................... functional endpoints findById:24, BookHandler (com.javaworld.webflux.bookservice.web) handle:-1, 953080701 (com.javaworld.webflux.bookservice.web.BookRouter$$Lambda$437) handle:61, HandlerFunctionAdapter (org.springframework.web.reactive.function.server.support) invokeHandler:168, DispatcherHandler (org.springframework.web.reactive) lambda$handle$1:160, DispatcherHandler (org.springframework.web.reactive) apply:-1, 1795086753 (org.springframework.web.reactive.DispatcherHandler$$Lambda$550) onNext:118, MonoFlatMap$FlatMapMain (reactor.core.publisher) onNext:67, FluxSwitchIfEmpty$SwitchIfEmptySubscriber (reactor.core.publisher) onNext:76, MonoNext$NextSubscriber (reactor.core.publisher)
参考资料
Mastering Spring framework 5, Part 2: Spring WebFlux