webflux系列--源码解析一

基础接口

webflux的基础接口类似于Spring MVC的几个主要组件。

DispatcherHandler

DispatcherHandler,它是WebFlux服务器端点处理的主要入口点,包括用于将请求映射到处理程序的关键协议,调用它们并处理结果。

该模块为反应式服务器端点提供两种编程模型。一个基于注释@Controller ,另一个基于功能路由和处理。该模块还包含一个功能性,反应式WebClient以及客户端和服务器,反应式WebSocket支持。

public class DispatcherHandler implements WebHandler, ApplicationContextAware {
	@Nullable
	private List<HandlerMapping> handlerMappings;
	@Nullable
	private List<HandlerAdapter> handlerAdapters;
	@Nullable
	private List<HandlerResultHandler> resultHandlers;
	public DispatcherHandler(ApplicationContext applicationContext) {
		initStrategies(applicationContext);
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) {
		initStrategies(applicationContext);
	}


	protected void initStrategies(ApplicationContext context) {
        //查找所有HandlerMapping类
		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);
		//获取所有HandlerAdapter
		Map<String, HandlerAdapter> adapterBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(
				context, HandlerAdapter.class, true, false);

		this.handlerAdapters = new ArrayList<>(adapterBeans.values());
		AnnotationAwareOrderComparator.sort(this.handlerAdapters);
		//获取所有HandlerResultHandler
		Map<String, HandlerResultHandler> beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(
				context, HandlerResultHandler.class, true, false);

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


	@Override
	public Mono<Void> handle(ServerWebExchange exchange) {
		if (this.handlerMappings == null) {
			return createNotFoundError();
		}
        
		return Flux.fromIterable(this.handlerMappings)
            //获取对应的handler
				.concatMap(mapping -> mapping.getHandler(exchange))
            //返回第一个元素
				.next()
            //如果未找得到handler,发送error信号
				.switchIfEmpty(createNotFoundError())
            //使用handler处理请求
				.flatMap(handler -> invokeHandler(exchange, handler))
            //处理handler调用返回的结果。
				.flatMap(result -> handleResult(exchange, result));
	}

	private <R> Mono<R> createNotFoundError() {
		return Mono.defer(() -> {
			Exception ex = new ResponseStatusException(HttpStatus.NOT_FOUND, "No matching handler");
			return Mono.error(ex);
		});
	}

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

	private HandlerResultHandler getResultHandler(HandlerResult handlerResult) {
		if (this.resultHandlers != null) {
			for (HandlerResultHandler resultHandler : this.resultHandlers) {
				if (resultHandler.supports(handlerResult)) {
					return resultHandler;
				}
			}
		}
		throw new IllegalStateException("No HandlerResultHandler for " + handlerResult.getReturnValue());
	}

}
public interface WebHandler {
	Mono<Void> handle(ServerWebExchange exchange);
}

HandlerMapping

查找给定请求的handler,如果找不到特定的请求,则返回一个空的Mono。

public interface HandlerMapping {
	String BEST_MATCHING_HANDLER_ATTRIBUTE = HandlerMapping.class.getName() + ".bestMatchingHandler";
	String BEST_MATCHING_PATTERN_ATTRIBUTE = HandlerMapping.class.getName() + ".bestMatchingPattern";
	String PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE = HandlerMapping.class.getName() + ".pathWithinHandlerMapping";
	String URI_TEMPLATE_VARIABLES_ATTRIBUTE = HandlerMapping.class.getName() + ".uriTemplateVariables";
	String MATRIX_VARIABLES_ATTRIBUTE = HandlerMapping.class.getName() + ".matrixVariables";
	String PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE = HandlerMapping.class.getName() + ".producibleMediaTypes";
	Mono<Object> getHandler(ServerWebExchange exchange);
}

HandlerAdapter

用获取到的handler处理请求。

public interface HandlerAdapter {
	boolean supports(Object handler);
	Mono<HandlerResult> handle(ServerWebExchange exchange, Object handler);
}

HandlerResult

处理结果。

public class HandlerResult {
	private final Object handler;
	@Nullable
	private final Object returnValue;
	private final ResolvableType returnType;
	private final BindingContext bindingContext;
	@Nullable
	private Function<Throwable, Mono<HandlerResult>> exceptionHandler;
}

HandlerResultHandler

处理 HandlerResult的handler。

public interface HandlerResultHandler {
	boolean supports(HandlerResult result);
	Mono<Void> handleResult(ServerWebExchange exchange, HandlerResult result);

}

handler包

AbstractHandlerMapping

AbstractHandlerMapping, ***HandlerMapping***实现的抽象基类。 类似于Spring MVC中的AbstractHandlerMapping,类继承结构基本上都差不多。

1610453334384
public abstract class AbstractHandlerMapping extends ApplicationObjectSupport
		implements HandlerMapping, Ordered, BeanNameAware {
	private static final WebHandler REQUEST_HANDLED_HANDLER = exchange -> Mono.empty();
	private final PathPatternParser patternParser;
	@Nullable
	private CorsConfigurationSource corsConfigurationSource;
	private CorsProcessor corsProcessor = new DefaultCorsProcessor();
	private int order = Ordered.LOWEST_PRECEDENCE;  // default: same as non-Ordered
	@Nullable
	private String beanName;

    	@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();
            //如果有cors配置或者
			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;
		});
	}
    /*由子类实现*/
    protected abstract Mono<?> getHandlerInternal(ServerWebExchange exchange);    
    

getHandler,在CORS 预先请求中,该方法应该返回一个匹配,而不是预先请求的请求,而是基于URL路径的预期实际请求,从“Access-Control-Request-Method”头,以及“Access-Control-Request-Headers”头的HTTP方法,通过 getcorsconfiguration获得CORS配置来允许通过。

AbstractUrlHandlerMapping

基于URL映射的HandlerMapping实现的抽象基类。

支持直接匹配,例如注册的“/ test”匹配“/ test”,以及各种ant样式匹配,例如, “/ test *”匹配“/ test”和“/ team”,“/ test / *”匹配“/ test”下的所有路径。

包含注册handler方法。

public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping {
	private boolean lazyInitHandlers = false;
	/*url与handler映射*/
	private final Map<PathPattern, Object> handlerMap = new LinkedHashMap<>();
    
    	@Override
	public Mono<Object> getHandlerInternal(ServerWebExchange exchange) {
        //从request获取path
		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);
        //抽取path
		PathContainer pathWithinMapping = pattern.extractPathWithinPattern(lookupPath);
		return handleMatch(this.handlerMap.get(pattern), pattern, pathWithinMapping, exchange);
	}
	//处理匹配的handler,因为有的是beanName,有的是handler。
	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;
	}

}

SimpleUrlHandlerMapping

AbstractUrlHandlerMapping的实现, 把url请求映射到对应的request handler的bean 。 支持映射到bean实例和映射到bean名称;非单例的handler需要映射到bean名称。

public class SimpleUrlHandlerMapping extends AbstractUrlHandlerMapping {
	/*映射 
    url 加前缀/,  beanName做trim*/
	private final Map<String, Object> urlMap = new LinkedHashMap<>();
    
}    

config包

config包内主要是一些用于辅助设置属性的类。

EnableWebFlux

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebFluxConfiguration.class)
public @interface EnableWebFlux {
}

WebFluxConfigurer

类似于Spring-Security 的Configurer。配置一些处理方式。

public interface WebFluxConfigurer {
//配置如何解决响应请求的内容类型。
	default void configureContentTypeResolver(RequestedContentTypeResolverBuilder builder) {
	}
	default void addCorsMappings(CorsRegistry registry) {
	}
	default void configurePathMatching(PathMatchConfigurer configurer) {
	}
	default void addResourceHandlers(ResourceHandlerRegistry registry) {
	}
	default void configureArgumentResolvers(ArgumentResolverConfigurer configurer) {
	}
	default void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
	}
	default void addFormatters(FormatterRegistry registry) {
	}
	@Nullable
	default Validator getValidator() {
		return null;
	}
	@Nullable
	default MessageCodesResolver getMessageCodesResolver() {
		return null;
	}
	default void configureViewResolvers(ViewResolverRegistry registry) {
	}

}

DelegatingWebFluxConfiguration

组合configurers的配置。

@Configuration(proxyBeanMethods = false)
public class DelegatingWebFluxConfiguration extends WebFluxConfigurationSupport {
	private final WebFluxConfigurerComposite configurers = new WebFluxConfigurerComposite();
}

PathMatchConfigurer

协助配置HandlerMapping的路径匹配选项。

public class PathMatchConfigurer {
	@Nullable
	private Boolean trailingSlashMatch;
	@Nullable
	private Boolean caseSensitiveMatch;
	@Nullable
	private Map<String, Predicate<Class<?>>> pathPrefixes;
}

CorsRegistration

协助创建映射到路径模式的CorsConfiguration实例。默认情况下,当最大时间设置为30分钟时,允许GET,HEAD和POST请求的所有来源,标题和凭证。

public class CorsRegistration {
	private final String pathPattern;
	private final CorsConfiguration config;
}

CorsRegistry

CorsRegistry协助注册CorsConfiguration映射到路径模式。 为指定的路径模式启用跨域请求处理

public class CorsRegistry {
	private final List<CorsRegistration> registrations = new ArrayList<>();
	/**加映射*/
	public CorsRegistration addMapping(String pathPattern) {
		CorsRegistration registration = new CorsRegistration(pathPattern);
		this.registrations.add(registration);
		return registration;
	}
}

ResourceHandlerRegistration

协助创建和配置静态资源处理程序。

public class ResourceHandlerRegistration {
	//用于将字符串位置转换为资源的资源加载器
	private final ResourceLoader resourceLoader;
	//一个或多个资源URL路径模式
	private final String[] pathPatterns;
	private final List<String> locationValues = new ArrayList<>();
	@Nullable
	private CacheControl cacheControl;
	@Nullable
	private ResourceChainRegistration resourceChainRegistration;
    //获取ResourceWebHandler
	protected ResourceWebHandler getRequestHandler() {
        //构造ResourceWebHandler,并设置属性。
		ResourceWebHandler handler = new ResourceWebHandler();
		handler.setLocationValues(this.locationValues);
		handler.setResourceLoader(this.resourceLoader);
		if (this.resourceChainRegistration != null) {
			handler.setResourceResolvers(this.resourceChainRegistration.getResourceResolvers());
			handler.setResourceTransformers(this.resourceChainRegistration.getResourceTransformers());
		}
		if (this.cacheControl != null) {
			handler.setCacheControl(this.cacheControl);
		}
		return handler;
	}    
}

ResourceHandlerRegistry

通过Spring WebFlux存储资源处理程序的注册,以提供静态资源(如图像,css文件和其他),包括设置优化的高速缓存头,以便在Web浏览器中进行高效加载。资源可以从Web应用程序根目录下的位置,类路径和其他位置提供。

public class ResourceHandlerRegistry {
	private final ResourceLoader resourceLoader;
    //Registration
	private final List<ResourceHandlerRegistration> registrations = new ArrayList<>();
	private int order = Ordered.LOWEST_PRECEDENCE - 1;
	@Nullable
	private ResourceUrlProvider resourceUrlProvider;
    //注册路径
	public ResourceHandlerRegistration addResourceHandler(String... patterns) {
		ResourceHandlerRegistration registration = new ResourceHandlerRegistration(this.resourceLoader, patterns);
		this.registrations.add(registration);
		return registration;
	}    
}

ViewResolverRegistry

协助配置一个ViewResolver的链,支持不同的模板机制。另外,还可以根据所请求的内容类型配置defaultView以进行渲染,例如, JSON,XML等

UrlBasedViewResolverRegistration

协助配置UrlBasedViewResolver的属性。

resource包

resource包下的类主要是为静态资源提供服务的类。

HttpResource

public interface HttpResource extends Resource {
	HttpHeaders getResponseHeaders();
}

ResourceResolver

处理 对服务器端资源的请求。

ublic interface ResourceResolver {

	/**将提供的请求和请求路径解析为存在于其中一个给定资源位置下的资源。*/
	Mono<Resource> resolveResource(@Nullable ServerWebExchange exchange, String requestPath,
			List<? extends Resource> locations, ResourceResolverChain chain);

	/**解析面向外部的公用URL路径,供客户端用来访问位于给定内部资源路径的资源。*/
	Mono<String> resolveUrlPath(String resourcePath, List<? extends Resource> locations,
			ResourceResolverChain chain);

}

1610509667803

ResourceResolverChain

public interface ResourceResolverChain {
	/***/
	Mono<Resource> resolveResource(@Nullable ServerWebExchange exchange, String requestPath,
			List<? extends Resource> locations);
	/***/
	Mono<String> resolveUrlPath(String resourcePath, List<? extends Resource> locations);

}

ResourceTransformer

资源转换器。

public interface ResourceTransformer {
	Mono<Resource> transform(ServerWebExchange exchange, Resource resource,
			ResourceTransformerChain transformerChain);
}

1610509695329

ResourceTransformerChain

public interface ResourceTransformerChain {
	ResourceResolverChain getResolverChain();
	Mono<Resource> transform(ServerWebExchange exchange, Resource resource);

}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值