Spring WebFlux 实现原理与架构图

启动原理与架构图

通过spring-boot-autoconfigure中的spring.factories文件,通过Spring Boot自动初始化下列类:HttpHandlerAutoConfiguration、ReactiveWebServerFactoryAutoConfiguration、WebFluxAutoConfiguration、ErrorWebFluxAutoConfiguration、ClientHttpConnectorAutoConfiguration、WebClientAutoConfiguration。

WebFluxAutoConfiguration

通过WebFluxConfig完成需要类的初始化,是通过EnableWebFluxConfiguration类完成,该类继承了WebFluxConfigurationSupport。

HttpHandlerAutoConfiguration

完成了将DispatcherHandler 和List<WebFilter>注入到DefaultWebFilterChain(该类实现了WebFilterChain)过滤链。形成了先执行WebFliter在执行DispatchHandler,并通过通过Mono.defer订阅Reactor服务。完成操作后通过HttpWebHandlerAdapter完成将HttpHandler转为WebHandler可执行的类。

架构图如下

在这里插入图片描述

WebFluxConfigurationSupport

初始化Bean

DispatcherHandler

@Bean
public DispatcherHandler webHandler() {
   return new DispatcherHandler();
}

DispatcherHandler主要执行方法:

  1. handle完成方法执行,循环所有HandlerMapping找到和ServerWebExchange 对应的HandlerMapping并去除Handler
  2. 通过invokeHandler方法循环所有HandlerAdapter找到对应的HandlerAdapter,由具体HandlerAdapter执行当前请求。
  3. 通过handleResult方法循环所有`HandlerResultHandler``找到对应的HandlerResultHandler,由具体的HandlerResultHandler完成结果最后的封装,并返回给前端。
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));
}
private Mono<HandlerResult> invokeHandler(ServerWebExchange exchange, Object handler) {
	if (this.handlerAdapters != null) {
		for (HandlerAdapter handlerAdapter : this.handlerAdapters) {
			if (handlerAdapter.supports(handler)) {
				return handlerAdapter.handle(exchange, handler);
			}
		}
	}
	return Mono.error(new IllegalStateException("No HandlerAdapter: " + handler));
}

private Mono<Void> handleResult(ServerWebExchange exchange, HandlerResult result) {
	return getResultHandler(result).handleResult(exchange, result)
			.checkpoint("Handler " + result.getHandler() + " [DispatcherHandler]")
			.onErrorResume(ex ->
					result.applyExceptionHandler(ex).flatMap(exResult -> {
						String text = "Exception handler " + exResult.getHandler() +
									", error=\"" + ex.getMessage() + "\" [DispatcherHandler]";
						return getResultHandler(exResult).handleResult(exchange, exResult).checkpoint(text);
					}));
}

HandlerMapping

RequestMappingHandlerMapping

从isHandler方法中可以知道这里只自动加载ControllerRequestMapping注解的类。
从createRequestMappingInfo方法中可以知道只加载方法上有RequestMapping注解方法。

@Bean
public RequestMappingHandlerMapping requestMappingHandlerMapping(
      @Qualifier("webFluxContentTypeResolver") RequestedContentTypeResolver contentTypeResolver) {

   RequestMappingHandlerMapping mapping = createRequestMappingHandlerMapping();
   mapping.setOrder(0);
   mapping.setContentTypeResolver(contentTypeResolver);
   mapping.setCorsConfigurations(getCorsConfigurations());

   PathMatchConfigurer configurer = getPathMatchConfigurer();
   Boolean useTrailingSlashMatch = configurer.isUseTrailingSlashMatch();
   if (useTrailingSlashMatch != null) {
      mapping.setUseTrailingSlashMatch(useTrailingSlashMatch);
   }
   Boolean useCaseSensitiveMatch = configurer.isUseCaseSensitiveMatch();
   if (useCaseSensitiveMatch != null) {
      mapping.setUseCaseSensitiveMatch(useCaseSensitiveMatch);
   }
   Map<String, Predicate<Class<?>>> pathPrefixes = configurer.getPathPrefixes();
   if (pathPrefixes != null) {
      mapping.setPathPrefixes(pathPrefixes);
   }

   return mapping;
}
protected boolean isHandler(Class<?> beanType) {
	return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) ||
			AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class));
}
private RequestMappingInfo createRequestMappingInfo(AnnotatedElement element) {
	RequestMapping requestMapping = AnnotatedElementUtils.findMergedAnnotation(element, RequestMapping.class);
	RequestCondition<?> condition = (element instanceof Class ?
				getCustomTypeCondition((Class<?>) element) : getCustomMethodCondition((Method) element));
	return (requestMapping != null ? createRequestMappingInfo(requestMapping, condition) : null);
}
RouterFunctionMapping

从routerFunctions方法中可以知道该类只加载Bean实现了RouterFunction接口的类。

@Bean
public RouterFunctionMapping routerFunctionMapping(ServerCodecConfigurer serverCodecConfigurer) {
   RouterFunctionMapping mapping = createRouterFunctionMapping();
   mapping.setOrder(-1);  // go before RequestMappingHandlerMapping
   mapping.setMessageReaders(serverCodecConfigurer.getReaders());
   mapping.setCorsConfigurations(getCorsConfigurations());
   return mapping;
}
private List<RouterFunction<?>> routerFunctions() {
	List<RouterFunction<?>> functions = obtainApplicationContext()
			.getBeanProvider(RouterFunction.class)
			.orderedStream()
			.map(router -> (RouterFunction<?>)router)
			.collect(Collectors.toList());
	return (!CollectionUtils.isEmpty(functions) ? functions : Collections.emptyList());
}
SimpleUrlHandlerMapping
@Bean
public HandlerMapping resourceHandlerMapping(ResourceUrlProvider resourceUrlProvider) {
   ResourceLoader resourceLoader = this.applicationContext;
   if (resourceLoader == null) {
      resourceLoader = new DefaultResourceLoader();
   }
   ResourceHandlerRegistry registry = new ResourceHandlerRegistry(resourceLoader);
   registry.setResourceUrlProvider(resourceUrlProvider);
   addResourceHandlers(registry);

   AbstractHandlerMapping handlerMapping = registry.getHandlerMapping();
   if (handlerMapping != null) {
      PathMatchConfigurer configurer = getPathMatchConfigurer();
      Boolean useTrailingSlashMatch = configurer.isUseTrailingSlashMatch();
      Boolean useCaseSensitiveMatch = configurer.isUseCaseSensitiveMatch();
      if (useTrailingSlashMatch != null) {
         handlerMapping.setUseTrailingSlashMatch(useTrailingSlashMatch);
      }
      if (useCaseSensitiveMatch != null) {
         handlerMapping.setUseCaseSensitiveMatch(useCaseSensitiveMatch);
      }
   }
   else {
      handlerMapping = new EmptyHandlerMapping();
   }
   return handlerMapping;
}

@Bean
public ResourceUrlProvider resourceUrlProvider() {
   return new ResourceUrlProvider();
}

HandlerAdapter

RequestMappingHandlerAdapter
@Bean
public RequestMappingHandlerAdapter requestMappingHandlerAdapter(
      @Qualifier("webFluxAdapterRegistry") ReactiveAdapterRegistry reactiveAdapterRegistry,
      ServerCodecConfigurer serverCodecConfigurer,
      @Qualifier("webFluxConversionService") FormattingConversionService conversionService,
      @Qualifier("webFluxValidator") Validator validator) {

   RequestMappingHandlerAdapter adapter = createRequestMappingHandlerAdapter();
   adapter.setMessageReaders(serverCodecConfigurer.getReaders());
   adapter.setWebBindingInitializer(getConfigurableWebBindingInitializer(conversionService, validator));
   adapter.setReactiveAdapterRegistry(reactiveAdapterRegistry);

   ArgumentResolverConfigurer configurer = new ArgumentResolverConfigurer();
   configureArgumentResolvers(configurer);
   adapter.setArgumentResolverConfigurer(configurer);

   return adapter;
}
HandlerFunctionAdapter
@Bean
public HandlerFunctionAdapter handlerFunctionAdapter() {
   return new HandlerFunctionAdapter();
}
SimpleHandlerAdapter
@Bean
public SimpleHandlerAdapter simpleHandlerAdapter() {
   return new SimpleHandlerAdapter();
}

HandlerResultHandler

ResponseEntityResultHandler
@Bean
public ResponseEntityResultHandler responseEntityResultHandler(
      @Qualifier("webFluxAdapterRegistry") ReactiveAdapterRegistry reactiveAdapterRegistry,
      ServerCodecConfigurer serverCodecConfigurer,
      @Qualifier("webFluxContentTypeResolver") RequestedContentTypeResolver contentTypeResolver) {

   return new ResponseEntityResultHandler(serverCodecConfigurer.getWriters(),
         contentTypeResolver, reactiveAdapterRegistry);
}
ResponseBodyResultHandler
@Bean
public ResponseBodyResultHandler responseBodyResultHandler(
      @Qualifier("webFluxAdapterRegistry") ReactiveAdapterRegistry reactiveAdapterRegistry,
      ServerCodecConfigurer serverCodecConfigurer,
      @Qualifier("webFluxContentTypeResolver") RequestedContentTypeResolver contentTypeResolver) {

   return new ResponseBodyResultHandler(serverCodecConfigurer.getWriters(),
         contentTypeResolver, reactiveAdapterRegistry);
}
ViewResolutionResultHandler
@Bean
public ViewResolutionResultHandler viewResolutionResultHandler(
      @Qualifier("webFluxAdapterRegistry") ReactiveAdapterRegistry reactiveAdapterRegistry,
      @Qualifier("webFluxContentTypeResolver") RequestedContentTypeResolver contentTypeResolver) {

   ViewResolverRegistry registry = getViewResolverRegistry();
   List<ViewResolver> resolvers = registry.getViewResolvers();
   ViewResolutionResultHandler handler = new ViewResolutionResultHandler(
         resolvers, contentTypeResolver, reactiveAdapterRegistry);
   handler.setDefaultViews(registry.getDefaultViews());
   handler.setOrder(registry.getOrder());
   return handler;
}
ServerResponseResultHandler
@Bean
public ServerResponseResultHandler serverResponseResultHandler(ServerCodecConfigurer serverCodecConfigurer) {
   List<ViewResolver> resolvers = getViewResolverRegistry().getViewResolvers();
   ServerResponseResultHandler handler = new ServerResponseResultHandler();
   handler.setMessageWriters(serverCodecConfigurer.getWriters());
   handler.setViewResolvers(resolvers);
   return handler;
}

DelegatingWebFluxConfiguration

继承WebFluxConfigurationSupport

EnableWebFluxConfiguration

HttpHandler

主要执行方法

Mono<Void> handle(ServerHttpRequest request, ServerHttpResponse response);

ContextPathCompositeHandler

HttpWebHandlerAdapter

继承了WebHandlerDecorator,,实现了HttpHandler
1.通过createExchange方法将ServerHttpRequest和ServerHttpResponse转换为ServerWebExchange供应WebHandler使用。
2.通过代理执行WebHandler的方法。
3.处理异常请求
4.成功返回。

public Mono<Void> handle(ServerHttpRequest request, ServerHttpResponse response) {
   if (this.forwardedHeaderTransformer != null) {
       try {
           request = this.forwardedHeaderTransformer.apply(request);
       } catch (Throwable var4) {
           if (logger.isDebugEnabled()) {
               logger.debug("Failed to apply forwarded headers to " + this.formatRequest(request), var4);
           }

           response.setStatusCode(HttpStatus.BAD_REQUEST);
           return response.setComplete();
       }
   }

   ServerWebExchange exchange = this.createExchange(request, response);
   LogFormatUtils.traceDebug(logger, (traceOn) -> {
       return exchange.getLogPrefix() + this.formatRequest(exchange.getRequest()) + (traceOn ? ", headers=" + this.formatHeaders(exchange.getRequest().getHeaders()) : "");
   });
   Mono var10000 = this.getDelegate().handle(exchange).doOnSuccess((aVoid) -> {
       this.logResponse(exchange);
   }).onErrorResume((ex) -> {
       return this.handleUnresolvedError(exchange, ex);
   });
   response.getClass();
   return var10000.then(Mono.defer(response::setComplete));
}

将ServerHttpRequest和ServerHttpResponse转换为ServerWebExchange

protected ServerWebExchange createExchange(ServerHttpRequest request, ServerHttpResponse response) {
   return new DefaultServerWebExchange(request, response, this.sessionManager, this.getCodecConfigurer(), this.getLocaleContextResolver(), this.applicationContext);
}

WebHandler

Mono<Void> handle(ServerWebExchange exchange);

FilteringWebHandler()

主要用于Gateway中过滤链的创建

private static List<GatewayFilter> loadFilters(List<GlobalFilter> filters) {
   return (List)filters.stream().map((filter) -> {
       GatewayFilterAdapter gatewayFilter = new GatewayFilterAdapter(filter);
       if (filter instanceof Ordered) {
           int order = ((Ordered)filter).getOrder();
           return new OrderedGatewayFilter(gatewayFilter, order);
       } else {
           return gatewayFilter;
       }
   }).collect(Collectors.toList());
}

public Mono<Void> handle(ServerWebExchange exchange) {
   Route route = (Route)exchange.getRequiredAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
   List<GatewayFilter> gatewayFilters = route.getFilters();
   List<GatewayFilter> combined = new ArrayList(this.globalFilters);
   combined.addAll(gatewayFilters);
   AnnotationAwareOrderComparator.sort(combined);
   if (logger.isDebugEnabled()) {
       logger.debug("Sorted gatewayFilterFactories: " + combined);
   }

   return (new DefaultGatewayFilterChain(combined)).filter(exchange);
}

ResourceWebHandler

处理资源请求。
检查配置的位置列表中是否存在请求的资源。如果资源不存在,将向客户端返回404响应。如果资源存在,则将检查请求是否存在Last Modified标头,并将其值与给定资源的最后修改的时间戳进行比较,如果Last Modified值更大,则返回304状态代码。如果资源比“上次修改”的值新,或者标头不存在,则资源的内容资源将写入到响应中,缓存标头将在一年后过期。

@Override
public Mono<Void> handle(ServerWebExchange exchange) {
   return getResource(exchange)
         .switchIfEmpty(Mono.defer(() -> {
            logger.debug(exchange.getLogPrefix() + "Resource not found");
            return Mono.error(new ResponseStatusException(HttpStatus.NOT_FOUND));
         }))
         .flatMap(resource -> {
            try {
               if (HttpMethod.OPTIONS.matches(exchange.getRequest().getMethodValue())) {
                  exchange.getResponse().getHeaders().add("Allow", "GET,HEAD,OPTIONS");
                  return Mono.empty();
               }

               // Supported methods and required session
               HttpMethod httpMethod = exchange.getRequest().getMethod();
               if (!SUPPORTED_METHODS.contains(httpMethod)) {
                  return Mono.error(new MethodNotAllowedException(
                        exchange.getRequest().getMethodValue(), SUPPORTED_METHODS));
               }

               // Header phase
               if (exchange.checkNotModified(Instant.ofEpochMilli(resource.lastModified()))) {
                  logger.trace(exchange.getLogPrefix() + "Resource not modified");
                  return Mono.empty();
               }

               // Apply cache settings, if any
               CacheControl cacheControl = getCacheControl();
               if (cacheControl != null) {
                  exchange.getResponse().getHeaders().setCacheControl(cacheControl);
               }

               // Check the media type for the resource
               MediaType mediaType = MediaTypeFactory.getMediaType(resource).orElse(null);
               setHeaders(exchange, resource, mediaType);

               // Content phase
               ResourceHttpMessageWriter writer = getResourceHttpMessageWriter();
               Assert.state(writer != null, "No ResourceHttpMessageWriter");
               return writer.write(Mono.just(resource),
                     null, ResolvableType.forClass(Resource.class), mediaType,
                     exchange.getRequest(), exchange.getResponse(),
                     Hints.from(Hints.LOG_PREFIX_HINT, exchange.getLogPrefix()));
            }
            catch (IOException ex) {
               return Mono.error(ex);
            }
         });
}

DispatcherHandler

@Nullable
private List<HandlerMapping> handlerMappings;

@Nullable
private List<HandlerAdapter> handlerAdapters;

@Nullable
private List<HandlerResultHandler> resultHandlers;

protected void initStrategies(ApplicationContext context) {
   Map<String, HandlerMapping> mappingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(
         context, HandlerMapping.class, true, false);

   ArrayList<HandlerMapping> mappings = new ArrayList<>(mappingBeans.values());
   AnnotationAwareOrderComparator.sort(mappings);
   this.handlerMappings = Collections.unmodifiableList(mappings);

   Map<String, HandlerAdapter> adapterBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(
         context, HandlerAdapter.class, true, false);

   this.handlerAdapters = new ArrayList<>(adapterBeans.values());
   AnnotationAwareOrderComparator.sort(this.handlerAdapters);

   Map<String, HandlerResultHandler> beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(
         context, HandlerResultHandler.class, true, false);

   this.resultHandlers = new ArrayList<>(beans.values());
   AnnotationAwareOrderComparator.sort(this.resultHandlers);
}

每次执行请求,都会到当前方法中
1.根据ServerWebExchange获取到对应的HandlerMapping。
2.在从HandlerMapping中获取到对应的Handler。
3.根据Handler选取对应的HandlerAdapter。由HandlerAdapter执行方法。
4.根据执行结果,选择对应的HandlerResultHandler。由其处理结果返回值。

@Override
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));
}

HandlerMapping(处理器Mapping)

返回此请求的处理器

Mono<Object> getHandler(ServerWebExchange exchange);
AbstractHandlerMapping(抽象处理器Mapping)

getHandler:根据请求获取到对应的Handler
1.通过getHandlerInternal方法获取到对应的控制器。
2.在通过map函数判断请求是否保护CORS,如则对Handler添加对应的信息。

@Override
public Mono<Object> getHandler(ServerWebExchange exchange) {
   return getHandlerInternal(exchange).map(handler -> {
      if (logger.isDebugEnabled()) {
         logger.debug(exchange.getLogPrefix() + "Mapped to " + handler);
      }
      ServerHttpRequest request = exchange.getRequest();
      if (hasCorsConfigurationSource(handler) || CorsUtils.isPreFlightRequest(request)) {
         CorsConfiguration config = (this.corsConfigurationSource != null ? this.corsConfigurationSource.getCorsConfiguration(exchange) : null);
         CorsConfiguration handlerConfig = getCorsConfiguration(handler, exchange);
         config = (config != null ? config.combine(handlerConfig) : handlerConfig);
         if (!this.corsProcessor.process(config, exchange) || CorsUtils.isPreFlightRequest(request)) {
            return REQUEST_HANDLED_HANDLER;
         }
      }
      return handler;
   });
}
AbstractHandlerMethodMapping

1.启动读锁,防止多线程执行时候出现数据异常
2.通过lookuphandlerMethod方法获取HandlerMethod
3.释放读锁

@Override
public Mono<HandlerMethod> getHandlerInternal(ServerWebExchange exchange) {
   this.mappingRegistry.acquireReadLock();
   try {
      HandlerMethod handlerMethod;
      try {
         handlerMethod = lookupHandlerMethod(exchange);
      }
      catch (Exception ex) {
         return Mono.error(ex);
      }
      if (handlerMethod != null) {
         handlerMethod = handlerMethod.createWithResolvedBean();
      }
      return Mono.justOrEmpty(handlerMethod);
   }
   finally {
      this.mappingRegistry.releaseReadLock();
   }
}

1.通过addMatchingMappings方法,获取到对应匹配的数据
2.

@Nullable
protected HandlerMethod lookupHandlerMethod(ServerWebExchange exchange) throws Exception {
   List<Match> matches = new ArrayList<>();
   addMatchingMappings(this.mappingRegistry.getMappings().keySet(), matches, exchange);

   if (!matches.isEmpty()) {
      Comparator<Match> comparator = new MatchComparator(getMappingComparator(exchange));
      matches.sort(comparator);
      Match bestMatch = matches.get(0);
      if (matches.size() > 1) {
         if (logger.isTraceEnabled()) {
            logger.trace(exchange.getLogPrefix() + matches.size() + " matching mappings: " + matches);
         }
         if (CorsUtils.isPreFlightRequest(exchange.getRequest())) {
            return PREFLIGHT_AMBIGUOUS_MATCH;
         }
         Match secondBestMatch = matches.get(1);
         if (comparator.compare(bestMatch, secondBestMatch) == 0) {
            Method m1 = bestMatch.handlerMethod.getMethod();
            Method m2 = secondBestMatch.handlerMethod.getMethod();
            RequestPath path = exchange.getRequest().getPath();
            throw new IllegalStateException(
                  "Ambiguous handler methods mapped for '" + path + "': {" + m1 + ", " + m2 + "}");
         }
      }
      handleMatch(bestMatch.mapping, bestMatch.handlerMethod, exchange);
      return bestMatch.handlerMethod;
   }
   else {
      return handleNoMatch(this.mappingRegistry.getMappings().keySet(), exchange);
   }
}

/**
* 新增匹配Mapping 
*/
private void addMatchingMappings(Collection<T> mappings, List<Match> matches, ServerWebExchange exchange) {
   for (T mapping : mappings) {
      T match = getMatchingMapping(mapping, exchange);
      if (match != null) {
         matches.add(new Match(match, this.mappingRegistry.getMappings().get(mapping)));
      }
   }
}

Handler Methods 发现
1.由InitializingBean执行AfetrPropertiesSet方法
2.获取上下文中所有Bean名称
3.如果Bean名称的开头是否是”scopedTarget.”
4.如果是则执行handlerMethodsInitialzed,本方式是一个空方法。
5.如果不是则,则从上下文中获取对应类。
6.通过isHandler()方法判断类是否是Handler类型,这里在类RequeMappingHandlerMapping中判断逻辑是注解@RequestMapping或是@Controller
7.通过类返射,将所有方法和对应的关系都注册到MappingRegistry

public void afterPropertiesSet() {

   initHandlerMethods();

   // Total includes detected mappings + explicit registrations via registerMapping..
   int total = this.getHandlerMethods().size();

   if ((logger.isTraceEnabled() && total == 0) || (logger.isDebugEnabled() && total > 0) ) {
      logger.debug(total + " mappings in " + formatMappingName());
   }
}


protected void initHandlerMethods() {
   String[] beanNames = obtainApplicationContext().getBeanNamesForType(Object.class);

   for (String beanName : beanNames) {
      if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX)) {
         Class<?> beanType = null;
         try {
            beanType = obtainApplicationContext().getType(beanName);
         }
         catch (Throwable ex) {
            // An unresolvable bean type, probably from a lazy bean - let's ignore it.
            if (logger.isTraceEnabled()) {
               logger.trace("Could not resolve type for bean '" + beanName + "'", ex);
            }
         }
         if (beanType != null && isHandler(beanType)) {
            detectHandlerMethods(beanName);
         }
      }
   }
   handlerMethodsInitialized(getHandlerMethods());
}


protected void detectHandlerMethods(final Object handler) {
   Class<?> handlerType = (handler instanceof String ?
         obtainApplicationContext().getType((String) handler) : handler.getClass());

   if (handlerType != null) {
      final Class<?> userType = ClassUtils.getUserClass(handlerType);
      Map<Method, T> methods = MethodIntrospector.selectMethods(userType,
            (MethodIntrospector.MetadataLookup<T>) method -> getMappingForMethod(method, userType));
      if (logger.isTraceEnabled()) {
         logger.trace(formatMappings(userType, methods));
      }
      methods.forEach((method, mapping) -> {
         Method invocableMethod = AopUtils.selectInvocableMethod(method, userType);
         registerHandlerMethod(handler, invocableMethod, mapping);
      });
   }
}
RequestMappingInfoHandlerMapping

1.通过RequestMappingInfo中获取到指定的RequeMappingInfo

@Override
protected RequestMappingInfo getMatchingMapping(RequestMappingInfo info, ServerWebExchange exchange) {
   return info.getMatchingCondition(exchange);
}

1.请求方法不能为OPTION或空
2.比对请求参数,是否匹配。 默认是不匹配。
3.请求头中,是否包含指定的头内容(去除Accept, Content-Type) 默认不匹配
4.请求头Content-Type中设置的类型是否支持,默认支持所有
5.支持的媒体类型,默认支持所有。
6.请求路径匹配,当前请求路径和实现的请求路径匹配
7.请求持有者判断,默认不进行。
8.当上述条件都满足时,创建RequestMappingInfo对象。

public RequestMappingInfo getMatchingCondition(ServerWebExchange exchange) {
   RequestMethodsRequestCondition methods = this.methodsCondition.getMatchingCondition(exchange);
   if (methods == null) {
      return null;
   }
   ParamsRequestCondition params = this.paramsCondition.getMatchingCondition(exchange);
   if (params == null) {
      return null;
   }
   HeadersRequestCondition headers = this.headersCondition.getMatchingCondition(exchange);
   if (headers == null) {
      return null;
   }
   // Match "Content-Type" and "Accept" (parsed ones and cached) before patterns
   ConsumesRequestCondition consumes = this.consumesCondition.getMatchingCondition(exchange);
   if (consumes == null) {
      return null;
   }
   ProducesRequestCondition produces = this.producesCondition.getMatchingCondition(exchange);
   if (produces == null) {
      return null;
   }
   PatternsRequestCondition patterns = this.patternsCondition.getMatchingCondition(exchange);
   if (patterns == null) {
      return null;
   }
   RequestConditionHolder custom = this.customConditionHolder.getMatchingCondition(exchange);
   if (custom == null) {
      return null;
   }
   return new RequestMappingInfo(this.name, patterns,
         methods, params, headers, consumes, produces, custom.getCondition());
}
RequestMappingHandlerMapping
@Nullable
private RequestMappingInfo createRequestMappingInfo(AnnotatedElement element) {
   RequestMapping requestMapping = AnnotatedElementUtils.findMergedAnnotation(element, RequestMapping.class);
   RequestCondition<?> condition = (element instanceof Class ?
         getCustomTypeCondition((Class<?>) element) : getCustomMethodCondition((Method) element));
   return (requestMapping != null ? createRequestMappingInfo(requestMapping, condition) : null);
}


protected RequestMappingInfo createRequestMappingInfo(
      RequestMapping requestMapping, @Nullable RequestCondition<?> customCondition) {

   RequestMappingInfo.Builder builder = RequestMappingInfo
         .paths(resolveEmbeddedValuesInPatterns(requestMapping.path()))
         .methods(requestMapping.method())
         .params(requestMapping.params())
         .headers(requestMapping.headers())
         .consumes(requestMapping.consumes())
         .produces(requestMapping.produces())
         .mappingName(requestMapping.name());
   if (customCondition != null) {
      builder.customCondition(customCondition);
   }
   return builder.options(this.config).build();
}

判断是否是Handler

@Override
protected boolean isHandler(Class<?> beanType) {
   return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) ||
         AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class));
}
AbstractUrlHandlerMapping
@Override
public Mono<Object> getHandlerInternal(ServerWebExchange exchange) {
   PathContainer lookupPath = exchange.getRequest().getPath().pathWithinApplication();
   Object handler;
   try {
      handler = lookupHandler(lookupPath, exchange);
   }
   catch (Exception ex) {
      return Mono.error(ex);
   }
   return Mono.justOrEmpty(handler);
}

protected Object lookupHandler(PathContainer lookupPath, ServerWebExchange exchange) throws Exception {

   List<PathPattern> matches = this.handlerMap.keySet().stream()
         .filter(key -> key.matches(lookupPath))
         .collect(Collectors.toList());

   if (matches.isEmpty()) {
      return null;
   }

   if (matches.size() > 1) {
      matches.sort(PathPattern.SPECIFICITY_COMPARATOR);
      if (logger.isTraceEnabled()) {
         logger.debug(exchange.getLogPrefix() + "Matching patterns " + matches);
      }
   }

   PathPattern pattern = matches.get(0);
   PathContainer pathWithinMapping = pattern.extractPathWithinPattern(lookupPath);
   return handleMatch(this.handlerMap.get(pattern), pattern, pathWithinMapping, exchange);
}

private Object handleMatch(Object handler, PathPattern bestMatch, PathContainer pathWithinMapping,
      ServerWebExchange exchange) {

   // Bean name or resolved handler?
   if (handler instanceof String) {
      String handlerName = (String) handler;
      handler = obtainApplicationContext().getBean(handlerName);
   }

   validateHandler(handler, exchange);

   exchange.getAttributes().put(BEST_MATCHING_HANDLER_ATTRIBUTE, handler);
   exchange.getAttributes().put(BEST_MATCHING_PATTERN_ATTRIBUTE, bestMatch);
   exchange.getAttributes().put(PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, pathWithinMapping);

   return handler;
}

注册Handler

protected void registerHandler(String urlPath, Object handler) throws BeansException, IllegalStateException {
   Assert.notNull(urlPath, "URL path must not be null");
   Assert.notNull(handler, "Handler object must not be null");
   Object resolvedHandler = handler;

   // Parse path pattern
   urlPath = prependLeadingSlash(urlPath);
   PathPattern pattern = getPathPatternParser().parse(urlPath);
   if (this.handlerMap.containsKey(pattern)) {
      Object existingHandler = this.handlerMap.get(pattern);
      if (existingHandler != null && existingHandler != resolvedHandler) {
         throw new IllegalStateException(
               "Cannot map " + getHandlerDescription(handler) + " to [" + urlPath + "]: " +
               "there is already " + getHandlerDescription(existingHandler) + " mapped.");
      }
   }

   // Eagerly resolve handler if referencing singleton via name.
   if (!this.lazyInitHandlers && handler instanceof String) {
      String handlerName = (String) handler;
      if (obtainApplicationContext().isSingleton(handlerName)) {
         resolvedHandler = obtainApplicationContext().getBean(handlerName);
      }
   }

   // Register resolved handler
   this.handlerMap.put(pattern, resolvedHandler);
   if (logger.isTraceEnabled()) {
      logger.trace("Mapped [" + urlPath + "] onto " + getHandlerDescription(handler));
   }
}
SimpleUrlHandlerMapping

初始化,并注册Handler

@Override
public void initApplicationContext() throws BeansException {
   super.initApplicationContext();
   registerHandlers(this.urlMap);
}

protected void registerHandlers(Map<String, Object> urlMap) throws BeansException {
   if (urlMap.isEmpty()) {
      logger.trace("No patterns in " + formatMappingName());
   }
   else {
      for (Map.Entry<String, Object> entry : urlMap.entrySet()) {
         String url = entry.getKey();
         Object handler = entry.getValue();
         // Prepend with slash if not already present.
         if (!url.startsWith("/")) {
            url = "/" + url;
         }
         // Remove whitespace from handler bean name.
         if (handler instanceof String) {
            handler = ((String) handler).trim();
         }
         registerHandler(url, handler);
      }
      if (logger.isDebugEnabled()) {
         logger.debug("Patterns " + getHandlerMap().keySet() + " in " + formatMappingName());
      }
   }
}
RouterFunctionMapping

初始化执行
1.由InitializingBean执行AfetrPropertiesSet方法
2.如果消息读物为空,通过ServerCodeConfigurer类创建
3.如果routerFunction(路由方法),为空,则通过initRouteFunctions方法创建
4.通过routerFunctions方法执行Lambda,从上下文件中获取Bean类型为RouterFunction.class类型的Bean。

@Override
public void afterPropertiesSet() throws Exception {
   if (CollectionUtils.isEmpty(this.messageReaders)) {
      ServerCodecConfigurer codecConfigurer = ServerCodecConfigurer.create();
      this.messageReaders = codecConfigurer.getReaders();
   }

   if (this.routerFunction == null) {
      initRouterFunctions();
   }
}
/**
* Initialized the router functions by detecting them in the application context.
*/
protected void initRouterFunctions() {
   List<RouterFunction<?>> routerFunctions = routerFunctions();
   this.routerFunction = routerFunctions.stream().reduce(RouterFunction::andOther).orElse(null);
   logRouterFunctions(routerFunctions);
}

private List<RouterFunction<?>> routerFunctions() {
   List<RouterFunction<?>> functions = obtainApplicationContext()
         .getBeanProvider(RouterFunction.class)
         .orderedStream()
         .map(router -> (RouterFunction<?>)router)
         .collect(Collectors.toList());
   return (!CollectionUtils.isEmpty(functions) ? functions : Collections.emptyList());
}

获取执行方法

@Override
protected Mono<?> getHandlerInternal(ServerWebExchange exchange) {
   if (this.routerFunction != null) {
      ServerRequest request = ServerRequest.create(exchange, this.messageReaders);
      return this.routerFunction.route(request)
            .doOnNext(handler -> setAttributes(exchange.getAttributes(), request, handler));
   }
   else {
      return Mono.empty();
   }
}

HandlerAdapter

是否执行当前Handler

boolean supports(Object handler);

执行Handler并返回结果

Mono<HandlerResult> handle(ServerWebExchange exchange, Object handler);
WebSocketHandlerAdapter
SimpleHandlerAdapter
RequestMappingHandlerAdapter

执行执行的Handler

public boolean supports(Object handler) {
   return handler instanceof HandlerMethod;
}

执行

@Override
public Mono<HandlerResult> handle(ServerWebExchange exchange, Object handler) {
   HandlerMethod handlerMethod = (HandlerMethod) handler;
   Assert.state(this.methodResolver != null && this.modelInitializer != null, "Not initialized");

   InitBinderBindingContext bindingContext = new InitBinderBindingContext(
         getWebBindingInitializer(), this.methodResolver.getInitBinderMethods(handlerMethod));

   InvocableHandlerMethod invocableMethod = this.methodResolver.getRequestMappingMethod(handlerMethod);

   Function<Throwable, Mono<HandlerResult>> exceptionHandler =
         ex -> handleException(ex, handlerMethod, bindingContext, exchange);

   return this.modelInitializer
         .initModel(handlerMethod, bindingContext, exchange)
         .then(Mono.defer(() -> invocableMethod.invoke(exchange, bindingContext)))
         .doOnNext(result -> result.setExceptionHandler(exceptionHandler))
         .doOnNext(result -> bindingContext.saveModel())
         .onErrorResume(exceptionHandler);
}
HandlerFunctionAdapter

HandlerResultHandler

ServerResponseResultHandler(响应Server)
ResponseBodyResultHandler(响应Body)
ViewResolutionResultHandler(视图解析)
public Mono<Void> handleResult(ServerWebExchange exchange, HandlerResult result) {
   Mono<Object> valueMono;
   ResolvableType valueType;
   ReactiveAdapter adapter = getAdapter(result);

   if (adapter != null) {
      if (adapter.isMultiValue()) {
         throw new IllegalArgumentException(
               "Multi-value reactive types not supported in view resolution: " + result.getReturnType());
      }

      valueMono = (result.getReturnValue() != null ?
            Mono.from(adapter.toPublisher(result.getReturnValue())) : Mono.empty());

      valueType = (adapter.isNoValue() ? ResolvableType.forClass(Void.class) :
            result.getReturnType().getGeneric());
   }
   else {
      valueMono = Mono.justOrEmpty(result.getReturnValue());
      valueType = result.getReturnType();
   }

   return valueMono
         .switchIfEmpty(exchange.isNotModified() ? Mono.empty() : NO_VALUE_MONO)
         .flatMap(returnValue -> {

            Mono<List<View>> viewsMono;
            Model model = result.getModel();
            MethodParameter parameter = result.getReturnTypeSource();
            Locale locale = LocaleContextHolder.getLocale(exchange.getLocaleContext());

            Class<?> clazz = valueType.toClass();
            if (clazz == Object.class) {
               clazz = returnValue.getClass();
            }

            if (returnValue == NO_VALUE || clazz == void.class || clazz == Void.class) {
               viewsMono = resolveViews(getDefaultViewName(exchange), locale);
            }
            else if (CharSequence.class.isAssignableFrom(clazz) && !hasModelAnnotation(parameter)) {
               viewsMono = resolveViews(returnValue.toString(), locale);
            }
            else if (Rendering.class.isAssignableFrom(clazz)) {
               Rendering render = (Rendering) returnValue;
               HttpStatus status = render.status();
               if (status != null) {
                  exchange.getResponse().setStatusCode(status);
               }
               exchange.getResponse().getHeaders().putAll(render.headers());
               model.addAllAttributes(render.modelAttributes());
               Object view = render.view();
               if (view == null) {
                  view = getDefaultViewName(exchange);
               }
               viewsMono = (view instanceof String ? resolveViews((String) view, locale) :
                     Mono.just(Collections.singletonList((View) view)));
            }
            else if (Model.class.isAssignableFrom(clazz)) {
               model.addAllAttributes(((Model) returnValue).asMap());
               viewsMono = resolveViews(getDefaultViewName(exchange), locale);
            }
            else if (Map.class.isAssignableFrom(clazz) && !hasModelAnnotation(parameter)) {
               model.addAllAttributes((Map<String, ?>) returnValue);
               viewsMono = resolveViews(getDefaultViewName(exchange), locale);
            }
            else if (View.class.isAssignableFrom(clazz)) {
               viewsMono = Mono.just(Collections.singletonList((View) returnValue));
            }
            else {
               String name = getNameForReturnValue(parameter);
               model.addAttribute(name, returnValue);
               viewsMono = resolveViews(getDefaultViewName(exchange), locale);
            }
            BindingContext bindingContext = result.getBindingContext();
            updateBindingResult(bindingContext, exchange);
            return viewsMono.flatMap(views -> render(views, model.asMap(), bindingContext, exchange));
         });
}
ResponseEntityResultHandler(响应Entity)

WebHandlerDecorator

通过代理执行对应的方法

public Mono<Void> handle(ServerWebExchange exchange) {
   return this.delegate.handle(exchange);
}

HttpWebHandlerAdapter

FilteringWebHandler(过滤WebHandler)

完成过滤链的创建

public FilteringWebHandler(WebHandler handler, List<WebFilter> filters) {
   super(handler);
   this.chain = new DefaultWebFilterChain(handler, filters);
}

ExceptionHandlingWebHandler(异常HandlingWebHandler)

初始化

public ExceptionHandlingWebHandler(WebHandler delegate, List<WebExceptionHandler> handlers) {
   super(delegate);
   List<WebExceptionHandler> handlersToUse = new ArrayList();
   handlersToUse.add(new CheckpointInsertingHandler());
   handlersToUse.addAll(handlers);
   this.exceptionHandlers = Collections.unmodifiableList(handlersToUse);
}

执行
1.先执行正常的WebHandler
2.执行完成之后,如果异常则执行所有异常类。

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;
}

RouterFunctionWebHandler

public Mono<Void> handle(ServerWebExchange exchange) {
   return Mono.defer(() -> {
      ServerRequest request = new DefaultServerRequest(exchange, this.strategies.messageReaders());
      addAttributes(exchange, request);
      return this.routerFunction.route(request)
            .defaultIfEmpty(notFound())
            .flatMap(handlerFunction -> wrapException(() -> handlerFunction.handle(request)))
            .flatMap(response -> wrapException(() -> response.writeTo(exchange,
                  new HandlerStrategiesResponseContext(this.strategies))));
   });
}

private void addAttributes(ServerWebExchange exchange, ServerRequest request) {
   Map<String, Object> attributes = exchange.getAttributes();
   attributes.put(REQUEST_ATTRIBUTE, request);
}

WebFilter

Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain);

Spring Boot AutoConfigurer自动配置

根据spring.factories有以下自动启类

HttpHandlerAutoConfiguration(HttpHandler自动配置)

HttpHandler完成了WebFilterChain的装配,使所有HTTP请求都经过WebFilterChain过滤执行。

@Configuration(proxyBeanMethods = false)
public static class AnnotationConfig {
   @Bean
   public HttpHandler httpHandler(ObjectProvider<WebFluxProperties> propsProvider) {
      HttpHandler httpHandler = WebHttpHandlerBuilder.applicationContext(this.applicationContext).build();
      WebFluxProperties properties = propsProvider.getIfAvailable();
      if (properties != null && StringUtils.hasText(properties.getBasePath())) {
         Map<String, HttpHandler> handlersMap = Collections.singletonMap(properties.getBasePath(), httpHandler);
         return new ContextPathCompositeHandler(handlersMap);
      }
      return httpHandler;
   }

}

WebHttpHandlerBuilder

创建WebHttpHandlerBuilder
1.通过上下文Bean获取名称为"webHandler"且类为WebHandler
2.通过上下文获取所有的WebFilter并进行排序。
3.对所有WebFilter类进行处理和过滤
4.通过上下文获取所有的WebExceptionHandler类并进行排序。
5.对所有WebExceptionHandler类进行处理和过滤
6.通过上下文Bean获取名称为"webSessionManager"且类为WebSessionManager
7.通过上下文Bean获取名称为"serverCodecConfigurer"且类为ServerCodecConfigurer
8.通过上下文Bean获取名称为"localeContextResolver"且类为LocaleContextResolver
9.通过上下文Bean获取名称为"forwardedHeaderTransformer"且类为ForwardedHeaderTransformer

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.forwardedHeaderTransformer(
            context.getBean(FORWARDED_HEADER_TRANSFORMER_BEAN_NAME, ForwardedHeaderTransformer.class));
   }
   catch (NoSuchBeanDefinitionException ex) {
      // Fall back on default
   }

   return builder;
}

1.HttpHandler的构造器
2.创建WebFilterChain过滤器通过FilteringWebHandler创建DefaultWebFilterChain,而DefaultWebFilterChain实现了WebFilterChain。
3.创建ExceptionHandlingWebHandler并将FilteringWebHandler设置进去。
4.创建HttpWebHandlerAdapter,并将WebHandler设置到adapted中。
5.

public HttpHandler build() {
   WebHandler decorated = new FilteringWebHandler(this.webHandler, this.filters);
   WebHandler 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;
}
FilteringWebHandler
public FilteringWebHandler(WebHandler handler, List<WebFilter> filters) {
   super(handler);
   this.chain = new DefaultWebFilterChain(handler, filters);
}
DefaultWebFilterChain

实现了WebFilterChain
初始化
1.创建DefaultWebFilterChain
2.通过initChain来创建过滤链,如果WebFliter存在多个。则创建WebFliter的链。

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, (WebFilter)null, (DefaultWebFilterChain)null);

   for(ListIterator<? extends WebFilter> iterator = filters.listIterator(filters.size()); iterator.hasPrevious(); chain = new DefaultWebFilterChain(filters, handler, (WebFilter)iterator.previous(), chain)) {
   }

   return chain;
}

过滤链执行
1.通过Mono.defer()完成订阅功能,当有事件发布(如:前端发起请求)的时候就可以收到。
2.判断当前currentFilter是否为空,不为空则执行WebFilter的过滤链,
3.当WebFilter执行完之后,执行WebHandler。

public Mono<Void> filter(ServerWebExchange exchange) {
   return Mono.defer(() -> {
       return this.currentFilter != null && this.chain != null ? this.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]");
}

ReactiveWebServerFactoryAutoConfiguration(ReactiveWeb服务器工厂自动配置)

默认支持4中方式自启动服务器:Tomcat、Jetty、Undertow、Netty

@Import({ ReactiveWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,
      ReactiveWebServerFactoryConfiguration.EmbeddedTomcat.class,
      ReactiveWebServerFactoryConfiguration.EmbeddedJetty.class,
      ReactiveWebServerFactoryConfiguration.EmbeddedUndertow.class,
      ReactiveWebServerFactoryConfiguration.EmbeddedNetty.class })

Spring-boot-starter-webflux默认启动是nettty

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-reactor-netty</artifactId>
 <version>2.3.12.RELEASE</version>
 <scope>compile</scope>
</dependency>

WebFluxAutoConfiguration(WebFlux自动配置)

OrderedHiddenHttpMethodFilter

继承自HiddenHttpMethodFilter并实现OrderedWebFilter,而HiddenHttpMethodFilter
实现了WebFilter

@Bean
@ConditionalOnMissingBean(HiddenHttpMethodFilter.class)
@ConditionalOnProperty(prefix = "spring.webflux.hiddenmethod.filter", name = "enabled", matchIfMissing = false)
public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
   return new OrderedHiddenHttpMethodFilter();
}

WebFluxConfig(WebFlux配置)

1.引入EnableWebFluxConfiguration类,在初始化当前类之前完成该类初始化。
2.启动配置参数ResourceProperties类和WebFluxProperties类
3.通过addResourceHandlers(添加资源Handlers)完成对"/webjars/**"目录和"classpath:/META-INF/resources/webjars/"目录资源的加载。 还可以通过WebFluxProperties配置添加自定义资源目录和本地目录。

@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties({ ResourceProperties.class, WebFluxProperties.class })
@Import({ EnableWebFluxConfiguration.class })
public static class WebFluxConfig implements WebFluxConfigurer { 
   @Override
   public void addResourceHandlers(ResourceHandlerRegistry registry) {
      if (!this.resourceProperties.isAddMappings()) {
         logger.debug("Default resource handling disabled");
         return;
      }
      if (!registry.hasMappingForPattern("/webjars/**")) {
         ResourceHandlerRegistration registration = registry.addResourceHandler("/webjars/**")
               .addResourceLocations("classpath:/META-INF/resources/webjars/");
         configureResourceCaching(registration);
         customizeResourceHandlerRegistration(registration);
      }
      String staticPathPattern = this.webFluxProperties.getStaticPathPattern();
      if (!registry.hasMappingForPattern(staticPathPattern)) {
         ResourceHandlerRegistration registration = registry.addResourceHandler(staticPathPattern)
               .addResourceLocations(this.resourceProperties.getStaticLocations());
         configureResourceCaching(registration);
         customizeResourceHandlerRegistration(registration);
      }
   }
}
EnableWebFluxConfiguration(启动WebFlux配置)

继承自DelegatingWebFluxConfiguration,而DelegatingWebFluxConfiguration继承自WebFluxConfigurationSupport
1.注解@Configuration实现自动转为Bean

@Configuration(proxyBeanMethods = false)
public static class EnableWebFluxConfiguration extends DelegatingWebFluxConfiguration {

   private final WebFluxProperties webFluxProperties;

   private final WebFluxRegistrations webFluxRegistrations;

   public EnableWebFluxConfiguration(WebFluxProperties webFluxProperties,
         ObjectProvider<WebFluxRegistrations> webFluxRegistrations) {
      this.webFluxProperties = webFluxProperties;
      this.webFluxRegistrations = webFluxRegistrations.getIfUnique();
   }

   @Bean
   @Override
   public FormattingConversionService webFluxConversionService() {
      Format format = this.webFluxProperties.getFormat();
      WebConversionService conversionService = new WebConversionService(new DateTimeFormatters()
            .dateFormat(format.getDate()).timeFormat(format.getTime()).dateTimeFormat(format.getDateTime()));
      addFormatters(conversionService);
      return conversionService;
   }

   @Bean
   @Override
   public Validator webFluxValidator() {
      if (!ClassUtils.isPresent("javax.validation.Validator", getClass().getClassLoader())) {
         return super.webFluxValidator();
      }
      return ValidatorAdapter.get(getApplicationContext(), getValidator());
   }

   @Override
   protected RequestMappingHandlerAdapter createRequestMappingHandlerAdapter() {
      if (this.webFluxRegistrations != null) {
         RequestMappingHandlerAdapter adapter = this.webFluxRegistrations.getRequestMappingHandlerAdapter();
         if (adapter != null) {
            return adapter;
         }
      }
      return super.createRequestMappingHandlerAdapter();
   }

   @Override
   protected RequestMappingHandlerMapping createRequestMappingHandlerMapping() {
      if (this.webFluxRegistrations != null) {
         RequestMappingHandlerMapping mapping = this.webFluxRegistrations.getRequestMappingHandlerMapping();
         if (mapping != null) {
            return mapping;
         }
      }
      return super.createRequestMappingHandlerMapping();
   }

}

ErrorWebFluxAutoConfiguration(异常WebFlux自动配置)

当异常时候的处理

ErrorWebExceptionHandler

@Bean
@ConditionalOnMissingBean(value = ErrorWebExceptionHandler.class, search = SearchStrategy.CURRENT)
@Order(-1)
public ErrorWebExceptionHandler errorWebExceptionHandler(ErrorAttributes errorAttributes,
      ResourceProperties resourceProperties, ObjectProvider<ViewResolver> viewResolvers,
      ServerCodecConfigurer serverCodecConfigurer, ApplicationContext applicationContext) {
   DefaultErrorWebExceptionHandler exceptionHandler = new DefaultErrorWebExceptionHandler(errorAttributes,
         resourceProperties, this.serverProperties.getError(), applicationContext);
   exceptionHandler.setViewResolvers(viewResolvers.orderedStream().collect(Collectors.toList()));
   exceptionHandler.setMessageWriters(serverCodecConfigurer.getWriters());
   exceptionHandler.setMessageReaders(serverCodecConfigurer.getReaders());
   return exceptionHandler;
}

DefaultErrorAttributes

@Bean
@ConditionalOnMissingBean(value = ErrorAttributes.class, search = SearchStrategy.CURRENT)
public DefaultErrorAttributes errorAttributes() {
   return new DefaultErrorAttributes();
}

ClientHttpConnectorAutoConfiguration(客户端Http连接自动配置)

WebClientCustomizer

@Bean
@Lazy
@Order(0)
@ConditionalOnBean(ClientHttpConnector.class)
public WebClientCustomizer clientConnectorCustomizer(ClientHttpConnector clientHttpConnector) {
   return (builder) -> builder.clientConnector(clientHttpConnector);
}

ClientHttpConnectorConfiguration

@Import({ ClientHttpConnectorConfiguration.ReactorNetty.class, ClientHttpConnectorConfiguration.JettyClient.class })

ReactorNetty
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(reactor.netty.http.client.HttpClient.class)
@ConditionalOnMissingBean(ClientHttpConnector.class)
public static class ReactorNetty {

   @Bean
   @ConditionalOnMissingBean
   public ReactorResourceFactory reactorClientResourceFactory() {
      return new ReactorResourceFactory();
   }
   @Bean
   @Lazy
   public ReactorClientHttpConnector reactorClientHttpConnector(ReactorResourceFactory reactorResourceFactory,
         ObjectProvider<ReactorNettyHttpClientMapper> mapperProvider) {
      ReactorNettyHttpClientMapper mapper = mapperProvider.orderedStream()
            .reduce((before, after) -> (client) -> after.configure(before.configure(client)))
            .orElse((client) -> client);
      return new ReactorClientHttpConnector(reactorResourceFactory, mapper::configure);
   }

}

WebClientAutoConfiguration(Web客户端自动配置)

@AutoConfigureAfter({ CodecsAutoConfiguration.class, 
ClientHttpConnectorAutoConfiguration.class })

WebClient

@Bean
@Scope("prototype")
@ConditionalOnMissingBean
public WebClient.Builder webClientBuilder(ObjectProvider<WebClientCustomizer> customizerProvider) {
   WebClient.Builder builder = WebClient.builder();
   customizerProvider.orderedStream().forEach((customizer) -> customizer.customize(builder));
   return builder;
}

WebClientCodecCustomizer

@Configuration(proxyBeanMethods = false)
@ConditionalOnBean(CodecCustomizer.class)
protected static class WebClientCodecsConfiguration {
   @Bean
   @ConditionalOnMissingBean
   @Order(0)
   public WebClientCodecCustomizer exchangeStrategiesCustomizer(ObjectProvider<CodecCustomizer> codecCustomizers) {
      return new WebClientCodecCustomizer(codecCustomizers.orderedStream().collect(Collectors.toList()));
   }
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Ktor和Spring WebFlux都是基于响应式编程的Web框架,它们具有许多相似之处,但也有一些区别。 1. 学习曲线 Ktor比Spring WebFlux的学习曲线更平滑,因为它的API更简洁,更容易理解和使用。它的DSL(领域特定语言)方式使得开发人员可以更快地编写代码,而不必了解太多的框架细节。然而,Spring WebFlux的学习曲线可能更陡峭,因为它是一个更大的框架,需要更多的学习和理解。 2. 性能 Ktor比Spring WebFlux在性能方面表现更好,因为它是一个更轻量级的框架。它可以处理更高的并发请求并具有更快的响应时间。然而,Spring WebFlux也具有很好的性能,并且可以轻松扩展到更大的应用程序。 3. 路由 Ktor的路由系统简单,易于使用,并且可以轻松地将路由映射到不同的处理程序。然而,Spring WebFlux的路由系统更加灵活,可以更好地处理复杂的路由映射。它还支持更多的路由选项,如正则表达式和路径变量。 4. 生态系统 Spring WebFlux具有更大的生态系统,因为它是Spring Framework的一部分。它有许多可用的插件和库,可以轻松地与其他Spring项目集成。另一方面,Ktor是一个相对较新的框架,它的生态系统较小,但它也有一些可用的插件和库。 综上所述,Ktor和Spring WebFlux都是优秀的Web框架,具有各自的优点和缺点。选择哪一个取决于您的需求和技术水平。如果您需要一个轻量级的框架,快速开发,并需要更好的性能,则Ktor可能是更好的选择。如果您需要一个更灵活的框架,并且已经熟悉了Spring Framework,则Spring WebFlux可能更适合您。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值