@EnableWebFlux
先看@EnableWebFlux的定义:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebFluxConfiguration.class)
public @interface EnableWebFlux {
}
这里引入的是DelegatingWebFluxConfiguration,如下:
@Configuration(proxyBeanMethods = false)
public class DelegatingWebFluxConfiguration extends WebFluxConfigurationSupport {
继承于WebFluxConfigurationSupport:
public class WebFluxConfigurationSupport implements ApplicationContextAware {
@Bean
public DispatcherHandler webHandler() {
return new DispatcherHandler();
}
}
可以看出这里引入了DispatcherHandler,对应beanName为webHandler
WebApplicationInitializer
这里对应的实现类为
public abstract class AbstractReactiveWebInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
String servletName = getServletName();
Assert.hasLength(servletName, "getServletName() must not return null or empty");
ApplicationContext applicationContext = createApplicationContext();
Assert.notNull(applicationContext, "createApplicationContext() must not return null");
refreshApplicationContext(applicationContext);
registerCloseListener(servletContext, applicationContext);
HttpHandler httpHandler = WebHttpHandlerBuilder.applicationContext(applicationContext).build();
ServletHttpHandlerAdapter servlet = new ServletHttpHandlerAdapter(httpHandler);
ServletRegistration.Dynamic registration = servletContext.addServlet(servletName, servlet);
if (registration == null) {
throw new IllegalStateException("Failed to register servlet with name '" + servletName + "'. " +
"Check if there is another servlet registered under the same name.");
}
registration.setLoadOnStartup(1);
registration.addMapping(getServletMapping());
registration.setAsyncSupported(true);
}
}
可以看出这里注册的servlet为ServletHttpHandlerAdapter,核心方法为service:
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
// Check for existing error attribute first
if (DispatcherType.ASYNC.equals(request.getDispatcherType())) {
Throwable ex = (Throwable) request.getAttribute(WRITE_ERROR_ATTRIBUTE_NAME);
throw new ServletException("Failed to create response content", ex);
}
// Start async before Read/WriteListener registration
AsyncContext asyncContext = request.startAsync();
asyncContext.setTimeout(-1);
ServletServerHttpRequest httpRequest;
try {
httpRequest = createRequest(((HttpServletRequest) request), asyncContext);
}
catch (URISyntaxException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to get request URL: " + ex.getMessage());
}
((HttpServletResponse) response).setStatus(400);
asyncContext.complete();
return;
}
ServerHttpResponse httpResponse = createResponse(((HttpServletResponse) response), asyncContext, httpRequest);
if (httpRequest.getMethod() == HttpMethod.HEAD) {
httpResponse = new HttpHeadResponseDecorator(httpResponse);
}
AtomicBoolean isCompleted = new AtomicBoolean();
HandlerResultAsyncListener listener = new HandlerResultAsyncListener(isCompleted, httpRequest);
asyncContext.addListener(listener);
HandlerResultSubscriber subscriber = new HandlerResultSubscriber(asyncContext, isCompleted, httpRequest);
this.httpHandler.handle(httpRequest, httpResponse).subscribe(subscriber);
}
这里创建一个订阅器为HandlerResultSubscriber,则真正的处理方法则为于handle方法,这里对应的则是WebHttpHandlerBuilder.applicationContext(applicationContext).build()创建的HttpHandler
WebHttpHandlerBuilder#applicationContext
public static WebHttpHandlerBuilder applicationContext(ApplicationContext context) {
WebHttpHandlerBuilder builder = new WebHttpHandlerBuilder(context.getBean(WEB_HANDLER_BEAN_NAME, WebHandler.class), context);
List<WebFilter> webFilters = context
.getBeanProvider(WebFilter.class)
.orderedStream()
.collect(Collectors.toList());
builder.filters(filters -> filters.addAll(webFilters));
List<WebExceptionHandler> exceptionHandlers = context
.getBeanProvider(WebExceptionHandler.class)
.orderedStream()
.collect(Collectors.toList());
builder.exceptionHandlers(handlers -> handlers.addAll(exceptionHandlers));
try {
builder.sessionManager(context.getBean(WEB_SESSION_MANAGER_BEAN_NAME, WebSessionManager.class));
}
catch (NoSuchBeanDefinitionException ex) {
// Fall back on default
}
try {
builder.codecConfigurer(context.getBean(SERVER_CODEC_CONFIGURER_BEAN_NAME, ServerCodecConfigurer.class));
}
catch (NoSuchBeanDefinitionException ex) {
// Fall back on default
}
try {
builder.localeContextResolver(
context.getBean(LOCALE_CONTEXT_RESOLVER_BEAN_NAME, LocaleContextResolver.class));
}
catch (NoSuchBeanDefinitionException ex) {
// Fall back on default
}
try {
builder.localeContextResolver(
context.getBean(LOCALE_CONTEXT_RESOLVER_BEAN_NAME, LocaleContextResolver.class));
}
catch (NoSuchBeanDefinitionException ex) {
// Fall back on default
}
try {
builder.forwardedHeaderTransformer(
context.getBean(FORWARDED_HEADER_TRANSFORMER_BEAN_NAME, ForwardedHeaderTransformer.class));
}
catch (NoSuchBeanDefinitionException ex) {
// Fall back on default
}
return builder;
}
WebHttpHandlerBuilder builder = new WebHttpHandlerBuilder(context.getBean(WEB_HANDLER_BEAN_NAME, WebHandler.class), context);这里限制了beanName为WEB_HANDLER_BEAN_NAME即webHandler,也就是上边的DispatcherHandler。
WebHttpHandlerBuilder#build
public HttpHandler build() {
WebHandler decorated = new FilteringWebHandler(this.webHandler, this.filters);
decorated = new ExceptionHandlingWebHandler(decorated, this.exceptionHandlers);
HttpWebHandlerAdapter adapted = new HttpWebHandlerAdapter(decorated);
if (this.sessionManager != null) {
adapted.setSessionManager(this.sessionManager);
}
if (this.codecConfigurer != null) {
adapted.setCodecConfigurer(this.codecConfigurer);
}
if (this.localeContextResolver != null) {
adapted.setLocaleContextResolver(this.localeContextResolver);
}
if (this.forwardedHeaderTransformer != null) {
adapted.setForwardedHeaderTransformer(this.forwardedHeaderTransformer);
}
if (this.applicationContext != null) {
adapted.setApplicationContext(this.applicationContext);
}
adapted.afterPropertiesSet();
return adapted;
}
可以看出这里进行了多层的嵌套:HttpWebHandlerAdapter->ExceptionHandlingWebHandler->FilteringWebHandler->DispatcherHandler
HttpWebHandlerAdapter
@Override
public Mono<Void> handle(ServerHttpRequest request, ServerHttpResponse response) {
if (this.forwardedHeaderTransformer != null) {
request = this.forwardedHeaderTransformer.apply(request);
}
ServerWebExchange exchange = createExchange(request, response);
LogFormatUtils.traceDebug(logger, traceOn -> exchange.getLogPrefix() + formatRequest(exchange.getRequest()) +
(traceOn ? ", headers=" + formatHeaders(exchange.getRequest().getHeaders()) : ""));
return getDelegate().handle(exchange)
.doOnSuccess(aVoid -> logResponse(exchange))
.onErrorResume(ex -> handleUnresolvedError(exchange, ex))
.then(Mono.defer(response::setComplete));
}
这里主要是创建了ServerWebExchange,增加了对请求成功/失败的处理,并调用ExceptionHandlingWebHandler的handle方法
ExceptionHandlingWebHandler
public Mono<Void> handle(ServerWebExchange exchange) {
Mono<Void> completion;
try {
completion = super.handle(exchange);
}
catch (Throwable ex) {
completion = Mono.error(ex);
}
for (WebExceptionHandler handler : this.exceptionHandlers) {
completion = completion.onErrorResume(ex -> handler.handle(exchange, ex));
}
return completion;
}
这里调用了父类即FilteringWebHandler的handle方法,调用之后依次调用了WebExceptionHandler的handle方法
FilteringWebHandler
public class FilteringWebHandler extends WebHandlerDecorator {
private final DefaultWebFilterChain chain;
/**
* Constructor.
* @param filters the chain of filters
*/
public FilteringWebHandler(WebHandler handler, List<WebFilter> filters) {
super(handler);
this.chain = new DefaultWebFilterChain(handler, filters);
}
@Override
public Mono<Void> handle(ServerWebExchange exchange) {
return this.chain.filter(exchange);
}
}
可以看出这里执行的是DefaultWebFilterChain的filter方法
DefaultWebFilterChain
public class DefaultWebFilterChain implements WebFilterChain {
public DefaultWebFilterChain(WebHandler handler, List<WebFilter> filters) {
Assert.notNull(handler, "WebHandler is required");
this.allFilters = Collections.unmodifiableList(filters);
this.handler = handler;
DefaultWebFilterChain chain = initChain(filters, handler);
this.currentFilter = chain.currentFilter;
this.chain = chain.chain;
}
private static DefaultWebFilterChain initChain(List<WebFilter> filters, WebHandler handler) {
DefaultWebFilterChain chain = new DefaultWebFilterChain(filters, handler, null, null);
ListIterator<? extends WebFilter> iterator = filters.listIterator(filters.size());
while (iterator.hasPrevious()) {
chain = new DefaultWebFilterChain(filters, handler, iterator.previous(), chain);
}
return chain;
}
public Mono<Void> filter(ServerWebExchange exchange) {
return Mono.defer(() ->
this.currentFilter != null && this.chain != null ? invokeFilter(this.currentFilter, this.chain, exchange) : this.handler.handle(exchange));
}
private Mono<Void> invokeFilter(WebFilter current, DefaultWebFilterChain chain, ServerWebExchange exchange) {
String currentName = current.getClass().getName();
return current.filter(exchange, chain).checkpoint(currentName + " [DefaultWebFilterChain]");
}
}
可以看出首先执行WebFilter所构成的过滤器链,最终执行WebHandler#handle方法
WebHandler->DispatcherHandler
这里WebHandler所对应的实现为DispatcherHandler:
public class DispatcherHandler implements WebHandler, ApplicationContextAware {
public Mono<Void> handle(ServerWebExchange exchange) {
if (this.handlerMappings == null) {
return createNotFoundError();
}
return Flux.fromIterable(this.handlerMappings)
.concatMap(mapping -> mapping.getHandler(exchange))
.next()
.switchIfEmpty(createNotFoundError())
.flatMap(handler -> invokeHandler(exchange, handler))
.flatMap(result -> handleResult(exchange, result));
}
}
这里和webMvc处理顺序是一致的,首先通过HandlerMapping找到对应的HandlerAdapter,调用HandlerAdapter的handle方法拿到HandlerResult,最后通过HandlerResult拿到对应的HandlerResultHandler处理后返回