目录
前言
流程
创建IOC容器
先创建IOC容器,ReactiveWebServerApplicationContext。
context = createApplicationContext();
invokeBeanPostProcessor
ConfigurationClassPostProcessor完成BeanDefinition的载入。
-
对应用的@Configuration的解析。【涉及条件过滤
@Conditional
,只有解析阶段的条件】 -
通过
this.deferredImportSelectorHandler.process();
对SpringBoot的自动配置类的引入跟解析。比如:ReactiveWebServerFactoryAutoConfiguration。2.1 在SpringBoot环境中,获取通过
grouping.getImports()
引入的自动配置类。这一阶段包含了从所有的自动配置类
->
符合条件的自动配置类->
对符合条件的自动配置类进行排序,以便按照该顺序载入loadBeanDefinitions,这个过程包含了对AutoConfigurationBefore和AutoConfigurationAfter及AutoConfigurationOrdered的处理。2.2 对每一个自动配置类进行解析处理。【涉及条件过滤
@Conditional
,只有解析阶段的条件】 -
向IOC容器中载入BeanDefinition。【涉及条件过滤
@Conditional
,只对bean注册的】
onRefresh
通过createWebServer();
完成WebServer的创建。
-
通过
getWebServerFactoryBeanName()
获取beanName:nettyReactiveWebServerFactory -
在IOC容器中根据beanName创建bean对象
注意一点,该beanName所对应的BeanDefinition信息是在invokeBeanPostProcessor阶段完成的。@Bean NettyReactiveWebServerFactory nettyReactiveWebServerFactory(ReactorResourceFactory resourceFactory, ObjectProvider<NettyRouteProvider> routes, ObjectProvider<NettyServerCustomizer> serverCustomizers) { NettyReactiveWebServerFactory serverFactory = new NettyReactiveWebServerFactory(); serverFactory.setResourceFactory(resourceFactory); routes.orderedStream().forEach(serverFactory::addRouteProviders); serverFactory.getServerCustomizers().addAll(serverCustomizers.orderedStream().collect(Collectors.toList())); return serverFactory; }
通过这种方式声明的Bean,并创建的Bean对象,是通过factoryMethodName创建的。
这个factoryMethodName和factoryBeanName是怎么来的?通过对配置类@Configuration的@Bean的解析和loadBeanDefinitions两个阶段完成。第一阶段的解析是完成配置类中所引入的bean,第二阶段是完成对配置类及其通过该配置类引入的beanDefinition信息的载入。
这个factoryMethodName和factoryBeanName分别有什么作用?
factoryMethodName和factoryBeanName最后都是利用反射执行方法来创建对象的,即:
Object result = factoryMethod.invoke(factoryBean, args);
。
实际执行的方法是:
如果这种声明@Bean,通过工厂方法创建对象的方式,该方法的参数需要一个集合类型的对象注入怎么办?就比如:nettyReactiveWebServerFactory不要用List的形式,直接用ObjectProvider<>的形式。而且,注入时机也是在工厂方法执行的时候。比如:
routes.orderedStream().forEach(serverFactory::addRouteProviders);
等。
-
对nettyReactiveWebServerFactory这个bean对象进行BeanPostProcessor处理,即WebServerFactoryCustomizerBeanPostProcessor。
-
通过
this.beanFactory.getBeansOfType(WebServerFactoryCustomizer.class, false, false)
获取WebServerFactoryCustomizer
。4.1 获取一个reactiveWebServerFactoryCustomizer的bean【反射执行】:
因为需要反射执行工厂方法reactiveWebServerFactoryCustomizer
,因此,需要该方法所在的对象即ReactiveWebServerFactoryAutoConfiguration。(该对象会优先创建)4.2 获取另一个nettyWebServerFactoryCustomizer的bean
-
对NettyReactiveWebServerFactory,用获得的WebServerFactoryCustomizer定制化操作。这个定制化,涉及的是比如yml中定义的相关属性赋值给NettyReactiveWebServerFactory等。
创建完NettyReactiveWebServerFactory后,接下来创建的是WebServerManager。
finishBeanFactoryInitialization
这一阶段完成剩余bean的创建。
- DefaultCodecsConfiguration
- defaultCodecCustomizer
- JacksonCodecConfiguration
- jacksonCodecCustomizer
- CodecsAutoConfiguration
- CodecProperties
- ErrorWebFluxAutoConfiguration等
finishRefresh
由LifeCycleAutoConfiguration自动配置类创建的DefaultLifecycleProcessor启动。
具体操作的是,getLifecycleProcessor().onRefresh();
。(所有的Web服务器,不管是Netty实现,还是Tomcat实现,亦或是Jetty,都是在这一阶段启动的)
在这一阶段中,通过getLifecycleBeans()
获取生命周期bean,即与Web有关的Server创建:
- lifecycleProcessor
- webServerGracefulShutdown
- webServerStartStop【创建WebServer服务器】,该bean的创建是在ReactiveWebServerApplicationContext中的onRefresh(IOC容器初始化阶段的onRefresh)阶段中。
对获得的每一个Lifecycle进行处理并启动:
if (!phases.isEmpty()) {
List<Integer> keys = new ArrayList<>(phases.keySet());
Collections.sort(keys);
for (Integer key : keys) {
// 先启动webServerStartStop = WebServerStartStopLifecycle
phases.get(key).start();
}
}
进入到WebServerStartStopLifecycle:
WebServerManage启动所做的工作:
-
httpHandler的初始化
- 获取httpHandler的Bean对象,其bean信息定义是在HttpHandlerAutoConfiguration
this.handler.initializeHandler()
→
this.handlerSupplier.get()
- 这个
this.handlerSupplier
其实就是在创建WebServerManager时传入的lambda函数:this::getHttpHandler
- 将获取到的HttpWebHandlerAdapter赋值给WebServerManager的delegate
-
启动webServer服务器,此处即NettyWebServer
- 此webServer对象的创建时机:
new WebServerManager
this.webServer = factory.getWebServer(this.handler);
- 此factory为NettyReactiveWebServerFactory
- 启动操作:
return server.bindNow();
Reactor编程:
public Mono<? extends DisposableServer> bind(TcpServer delegate) { return delegate.bootstrap(this) .bind() .map(CLEANUP_GLOBAL_RESOURCE); }
这里的bind方法最终是调用TcpServerBind中的
bind(ServerBootstrap b)
方法。
实际创建Mono对象也是在此方法中:return Mono.create(sink -> { ServerBootstrap bootstrap = b.clone(); ConnectionObserver obs = BootstrapHandlers.connectionObserver(bootstrap); ConnectionObserver childObs = BootstrapHandlers.childConnectionObserver(bootstrap); ChannelOperations.OnSetup ops = BootstrapHandlers.channelOperationFactory(bootstrap); convertLazyLocalAddress(bootstrap); BootstrapHandlers.finalizeHandler(bootstrap, ops, new ChildObserver(childObs)); ChannelFuture f = bootstrap.bind(); DisposableBind disposableServer = new DisposableBind(sink, f, obs, bootstrap); f.addListener(disposableServer); sink.onCancel(disposableServer); });
在map方法中做的是订阅工作。
@Nullable public T block(Duration timeout) { // 一个特定功能的CountDownLatch BlockingMonoSubscriber<T> subscriber = new BlockingMonoSubscriber<>(); // 订阅,这里会执行Mono.create时的参数函数 subscribe((Subscriber<T>) subscriber); // 获取 return subscriber.blockingGet(timeout.toMillis(), TimeUnit.MILLISECONDS); }
这也是,官方中为什么说,SpringBoot中提供的Reactive编程是基于Reactor构建的。
- 此webServer对象的创建时机:
HttpServerTcpConfig【层级关系,以防回头再看,从头再理解】
依次向下创建:每次创建本次HttpServerTcpConfig,都把上一次创建的HttpServerTcpConfig传进去。当执行bind(tcpConfiguration())
的时候,根据tcpServerMapper.apply(source.tcpConfiguration()
执行关于TcpServer的Function。不然,跳过来跳过去,不知做什么。
HttpServerBind - Function【bind】
HttpServerTcpConfig - Function【protocols】
HttpServerTcpConfig - Function【Forward】
HttpServerTcpConfig - Function【请求解码】
HttpServerTcpConfig - Function【channelGroup】