类org.springframework.core.ReactiveAdapter源码实例Demo

下面列出了怎么用org.springframework.core.ReactiveAdapter的API类实例代码及写法,或者点击链接到github查看源代码。

@Override
public boolean supports(HandlerResult result) {
	if (hasModelAnnotation(result.getReturnTypeSource())) {
		return true;
	}

	Class<?> type = result.getReturnType().toClass();
	ReactiveAdapter adapter = getAdapter(result);
	if (adapter != null) {
		if (adapter.isNoValue()) {
			return true;
		}
		type = result.getReturnType().getGeneric().toClass();
	}

	return (CharSequence.class.isAssignableFrom(type) || Rendering.class.isAssignableFrom(type) ||
			Model.class.isAssignableFrom(type) || Map.class.isAssignableFrom(type) ||
			void.class.equals(type) || View.class.isAssignableFrom(type) ||
			!BeanUtils.isSimpleProperty(type));
}
 
private Mono<?> prepareAttributeMono(String attributeName, ResolvableType attributeType,
		BindingContext context, ServerWebExchange exchange) {

	Object attribute = context.getModel().asMap().get(attributeName);

	if (attribute == null) {
		attribute = findAndRemoveReactiveAttribute(context.getModel(), attributeName);
	}

	if (attribute == null) {
		return createAttribute(attributeName, attributeType.toClass(), context, exchange);
	}

	ReactiveAdapter adapter = getAdapterRegistry().getAdapter(null, attribute);
	if (adapter != null) {
		Assert.isTrue(!adapter.isMultiValue(), "Data binding only supports single-value async types");
		return Mono.from(adapter.toPublisher(attribute));
	}
	else {
		return Mono.justOrEmpty(attribute);
	}
}
 
@Nullable
private Object findAndRemoveReactiveAttribute(Model model, String attributeName) {
	return model.asMap().entrySet().stream()
			.filter(entry -> {
				if (!entry.getKey().startsWith(attributeName)) {
					return false;
				}
				ReactiveAdapter adapter = getAdapterRegistry().getAdapter(null, entry.getValue());
				if (adapter == null) {
					return false;
				}
				String name = attributeName + ClassUtils.getShortName(adapter.getReactiveType());
				return entry.getKey().equals(name);
			})
			.findFirst()
			.map(entry -> {
				// Remove since we will be re-inserting the resolved attribute value
				model.asMap().remove(entry.getKey());
				return entry.getValue();
			})
			.orElse(null);
}
 
private Object getErrors(MethodParameter parameter, BindingContext context) {
	Assert.isTrue(parameter.getParameterIndex() > 0,
			"Errors argument must be declared immediately after a model attribute argument");

	int index = parameter.getParameterIndex() - 1;
	MethodParameter attributeParam = MethodParameter.forExecutable(parameter.getExecutable(), index);
	ReactiveAdapter adapter = getAdapterRegistry().getAdapter(attributeParam.getParameterType());

	Assert.state(adapter == null, "An @ModelAttribute and an Errors/BindingResult argument " +
			"cannot both be declared with an async type wrapper. " +
			"Either declare the @ModelAttribute without an async wrapper type or " +
			"handle a WebExchangeBindException error signal through the async type.");

	ModelAttribute ann = parameter.getParameterAnnotation(ModelAttribute.class);
	String name = (ann != null && StringUtils.hasText(ann.value()) ?
			ann.value() : Conventions.getVariableNameForParameter(attributeParam));
	Object errors = context.getModel().asMap().get(BindingResult.MODEL_KEY_PREFIX + name);

	Assert.state(errors != null, () -> "An Errors/BindingResult argument is expected " +
			"immediately after the @ModelAttribute argument to which it applies. " +
			"For @RequestBody and @RequestPart arguments, please declare them with a reactive " +
			"type wrapper and use its onError operators to handle WebExchangeBindException: " +
			parameter.getMethod());

	return errors;
}
 
@Override
protected Object resolveNamedValue(String name, MethodParameter parameter, ServerWebExchange exchange) {
	Object value = exchange.getAttribute(name);
	ReactiveAdapter toAdapter = getAdapterRegistry().getAdapter(parameter.getParameterType());
	if (toAdapter != null) {
		if (value == null) {
			Assert.isTrue(toAdapter.supportsEmpty(),
					() -> "No request attribute '" + name + "' and target type " +
							parameter.getGenericParameterType() + " doesn't support empty values.");
			return toAdapter.fromPublisher(Mono.empty());
		}
		if (parameter.getParameterType().isAssignableFrom(value.getClass())) {
			return value;
		}
		ReactiveAdapter fromAdapter = getAdapterRegistry().getAdapter(value.getClass());
		Assert.isTrue(fromAdapter != null,
				() -> getClass().getSimpleName() + " doesn't support " +
						"reactive type wrapper: " + parameter.getGenericParameterType());
		return toAdapter.fromPublisher(fromAdapter.toPublisher(value));
	}
	return value;
}
 
/**
 * Evaluate the {@code Predicate} on the method parameter type but raise an
 * {@code IllegalStateException} if the same matches the generic type
 * within a reactive type wrapper.
 */
protected boolean checkParameterTypeNoReactiveWrapper(MethodParameter parameter, Predicate<Class<?>> predicate) {
	Class<?> type = parameter.getParameterType();
	ReactiveAdapter adapter = getAdapterRegistry().getAdapter(type);
	if (adapter != null) {
		assertHasValues(adapter, parameter);
		type = parameter.nested().getNestedParameterType();
	}
	if (predicate.test(type)) {
		if (adapter == null) {
			return true;
		}
		throw buildReactiveWrapperException(parameter);
	}
	return false;
}
 
@Override
public boolean supports(HandlerResult result) {
	if (hasModelAnnotation(result.getReturnTypeSource())) {
		return true;
	}

	Class<?> type = result.getReturnType().toClass();
	ReactiveAdapter adapter = getAdapter(result);
	if (adapter != null) {
		if (adapter.isNoValue()) {
			return true;
		}
		type = result.getReturnType().getGeneric().toClass();
	}

	return (CharSequence.class.isAssignableFrom(type) || Rendering.class.isAssignableFrom(type) ||
			Model.class.isAssignableFrom(type) || Map.class.isAssignableFrom(type) ||
			void.class.equals(type) || View.class.isAssignableFrom(type) ||
			!BeanUtils.isSimpleProperty(type));
}
 
private Mono<?> prepareAttributeMono(String attributeName, ResolvableType attributeType,
		BindingContext context, ServerWebExchange exchange) {

	Object attribute = context.getModel().asMap().get(attributeName);

	if (attribute == null) {
		attribute = findAndRemoveReactiveAttribute(context.getModel(), attributeName);
	}

	if (attribute == null) {
		return createAttribute(attributeName, attributeType.toClass(), context, exchange);
	}

	ReactiveAdapter adapterFrom = getAdapterRegistry().getAdapter(null, attribute);
	if (adapterFrom != null) {
		Assert.isTrue(!adapterFrom.isMultiValue(), "Data binding only supports single-value async types");
		return Mono.from(adapterFrom.toPublisher(attribute));
	}
	else {
		return Mono.justOrEmpty(attribute);
	}
}
 
@Nullable
private Object findAndRemoveReactiveAttribute(Model model, String attributeName) {
	return model.asMap().entrySet().stream()
			.filter(entry -> {
				if (!entry.getKey().startsWith(attributeName)) {
					return false;
				}
				ReactiveAdapter adapter = getAdapterRegistry().getAdapter(null, entry.getValue());
				if (adapter == null) {
					return false;
				}
				String name = attributeName + ClassUtils.getShortName(adapter.getReactiveType());
				return entry.getKey().equals(name);
			})
			.findFirst()
			.map(entry -> {
				// Remove since we will be re-inserting the resolved attribute value
				model.asMap().remove(entry.getKey());
				return entry.getValue();
			})
			.orElse(null);
}
 
private Object getErrors(MethodParameter parameter, BindingContext context) {
	Assert.isTrue(parameter.getParameterIndex() > 0,
			"Errors argument must be declared immediately after a model attribute argument");

	int index = parameter.getParameterIndex() - 1;
	MethodParameter attributeParam = MethodParameter.forExecutable(parameter.getExecutable(), index);
	ReactiveAdapter adapter = getAdapterRegistry().getAdapter(attributeParam.getParameterType());

	Assert.state(adapter == null, "An @ModelAttribute and an Errors/BindingResult argument " +
			"cannot both be declared with an async type wrapper. " +
			"Either declare the @ModelAttribute without an async wrapper type or " +
			"handle a WebExchangeBindException error signal through the async type.");

	ModelAttribute ann = parameter.getParameterAnnotation(ModelAttribute.class);
	String name = (ann != null && StringUtils.hasText(ann.value()) ?
			ann.value() : Conventions.getVariableNameForParameter(attributeParam));
	Object errors = context.getModel().asMap().get(BindingResult.MODEL_KEY_PREFIX + name);

	Assert.state(errors != null, () -> "An Errors/BindingResult argument is expected " +
			"immediately after the @ModelAttribute argument to which it applies. " +
			"For @RequestBody and @RequestPart arguments, please declare them with a reactive " +
			"type wrapper and use its onError operators to handle WebExchangeBindException: " +
			parameter.getMethod());

	return errors;
}
 
@Override
protected Object resolveNamedValue(String name, MethodParameter parameter, ServerWebExchange exchange) {
	Object value = exchange.getAttribute(name);
	ReactiveAdapter toAdapter = getAdapterRegistry().getAdapter(parameter.getParameterType());
	if (toAdapter != null) {
		if (value == null) {
			Assert.isTrue(toAdapter.supportsEmpty(),
					() -> "No request attribute '" + name + "' and target type " +
							parameter.getGenericParameterType() + " doesn't support empty values.");
			return toAdapter.fromPublisher(Mono.empty());
		}
		if (parameter.getParameterType().isAssignableFrom(value.getClass())) {
			return value;
		}
		ReactiveAdapter fromAdapter = getAdapterRegistry().getAdapter(value.getClass());
		Assert.isTrue(fromAdapter != null,
				() -> getClass().getSimpleName() + " doesn't support " +
						"reactive type wrapper: " + parameter.getGenericParameterType());
		return toAdapter.fromPublisher(fromAdapter.toPublisher(value));
	}
	return value;
}
 
/**
 * Evaluate the {@code Predicate} on the method parameter type but raise an
 * {@code IllegalStateException} if the same matches the generic type
 * within a reactive type wrapper.
 */
protected boolean checkParameterTypeNoReactiveWrapper(MethodParameter parameter, Predicate<Class<?>> predicate) {
	Class<?> type = parameter.getParameterType();
	ReactiveAdapter adapter = getAdapterRegistry().getAdapter(type);
	if (adapter != null) {
		assertHasValues(adapter, parameter);
		type = parameter.nested().getNestedParameterType();
	}
	if (predicate.test(type)) {
		if (adapter == null) {
			return true;
		}
		throw buildReactiveWrapperException(parameter);
	}
	return false;
}
 
@SuppressWarnings("unchecked")
private Flux<DataBuffer> encodeContent(
		@Nullable Object content, MethodParameter returnType, DataBufferFactory bufferFactory,
		@Nullable MimeType mimeType, Map<String, Object> hints) {

	ResolvableType returnValueType = ResolvableType.forMethodParameter(returnType);
	ReactiveAdapter adapter = getAdapterRegistry().getAdapter(returnValueType.resolve(), content);

	Publisher<?> publisher;
	ResolvableType elementType;
	if (adapter != null) {
		publisher = adapter.toPublisher(content);
		boolean isUnwrapped = KotlinDetector.isKotlinReflectPresent() &&
				KotlinDetector.isKotlinType(returnType.getContainingClass()) &&
				KotlinDelegate.isSuspend(returnType.getMethod()) &&
				!COROUTINES_FLOW_CLASS_NAME.equals(returnValueType.toClass().getName());
		ResolvableType genericType = isUnwrapped ? returnValueType : returnValueType.getGeneric();
		elementType = getElementType(adapter, genericType);
	}
	else {
		publisher = Mono.justOrEmpty(content);
		elementType = (returnValueType.toClass() == Object.class && content != null ?
				ResolvableType.forInstance(content) : returnValueType);
	}

	if (elementType.resolve() == void.class || elementType.resolve() == Void.class) {
		return Flux.from(publisher).cast(DataBuffer.class);
	}

	Encoder<?> encoder = getEncoder(elementType, mimeType);
	return Flux.from((Publisher) publisher).map(value ->
			encodeValue(value, elementType, encoder, bufferFactory, mimeType, hints));
}
 
private ResolvableType getElementType(ReactiveAdapter adapter, ResolvableType type) {
	if (adapter.isNoValue()) {
		return VOID_RESOLVABLE_TYPE;
	}
	else if (type != ResolvableType.NONE) {
		return type;
	}
	else {
		return OBJECT_RESOLVABLE_TYPE;
	}
}
 
private boolean isAsyncVoidReturnType(MethodParameter returnType, @Nullable ReactiveAdapter reactiveAdapter) {
	if (reactiveAdapter != null && reactiveAdapter.supportsEmpty()) {
		if (reactiveAdapter.isNoValue()) {
			return true;
		}
		Type parameterType = returnType.getGenericParameterType();
		if (parameterType instanceof ParameterizedType) {
			ParameterizedType type = (ParameterizedType) parameterType;
			if (type.getActualTypeArguments().length == 1) {
				return Void.class.equals(type.getActualTypeArguments()[0]);
			}
		}
	}
	return false;
}
 
源代码16 项目: spring-analysis-note   文件: ModelInitializer.java
private Mono<Void> handleResult(HandlerResult handlerResult, BindingContext bindingContext) {
	Object value = handlerResult.getReturnValue();
	if (value != null) {
		ResolvableType type = handlerResult.getReturnType();
		ReactiveAdapter adapter = this.adapterRegistry.getAdapter(type.resolve(), value);
		if (isAsyncVoidType(type, adapter)) {
			return Mono.from(adapter.toPublisher(value));
		}
		String name = getAttributeName(handlerResult.getReturnTypeSource());
		bindingContext.getModel().asMap().putIfAbsent(name, value);
	}
	return Mono.empty();
}
 
@Override
public boolean supports(HandlerResult result) {
	Class<?> valueType = resolveReturnValueType(result);
	if (isSupportedType(valueType)) {
		return true;
	}
	ReactiveAdapter adapter = getAdapter(result);
	return adapter != null && !adapter.isNoValue() &&
			isSupportedType(result.getReturnType().getGeneric().toClass());
}
 
private ResolvableType getElementType(ReactiveAdapter adapter, ResolvableType genericType) {
	if (adapter.isNoValue()) {
		return ResolvableType.forClass(Void.class);
	}
	else if (genericType != ResolvableType.NONE) {
		return genericType;
	}
	else {
		return ResolvableType.forClass(Object.class);
	}
}
 
@Override
public Mono<Object> resolveArgument(
		MethodParameter parameter, BindingContext context, ServerWebExchange exchange) {

	Mono<Principal> principal = exchange.getPrincipal();
	ReactiveAdapter adapter = getAdapterRegistry().getAdapter(parameter.getParameterType());
	return (adapter != null ? Mono.just(adapter.fromPublisher(principal)) : Mono.from(principal));
}
 
@Override
public Mono<Object> resolveArgument(
		MethodParameter parameter, BindingContext context, ServerWebExchange exchange) {

	Mono<WebSession> session = exchange.getSession();
	ReactiveAdapter adapter = getAdapterRegistry().getAdapter(parameter.getParameterType());
	return (adapter != null ? Mono.just(adapter.fromPublisher(session)) : Mono.from(session));
}
 
/**
 * Evaluate the {@code Predicate} on the method parameter type or on
 * the generic type within a reactive type wrapper.
 */
protected boolean checkParameterType(MethodParameter parameter, Predicate<Class<?>> predicate) {
	Class<?> type = parameter.getParameterType();
	ReactiveAdapter adapter = getAdapterRegistry().getAdapter(type);
	if (adapter != null) {
		assertHasValues(adapter, parameter);
		type = parameter.nested().getNestedParameterType();
	}
	return predicate.test(type);
}
 
/**
 * Evaluate the {@code Predicate} on the method parameter type if it has the
 * given annotation, nesting within {@link java.util.Optional} if necessary,
 * but raise an {@code IllegalStateException} if the same matches the generic
 * type within a reactive type wrapper.
 */
protected <A extends Annotation> boolean checkAnnotatedParamNoReactiveWrapper(
		MethodParameter parameter, Class<A> annotationType, BiPredicate<A, Class<?>> typePredicate) {

	A annotation = parameter.getParameterAnnotation(annotationType);
	if (annotation == null) {
		return false;
	}

	parameter = parameter.nestedIfOptional();
	Class<?> type = parameter.getNestedParameterType();

	ReactiveAdapter adapter = getAdapterRegistry().getAdapter(type);
	if (adapter != null) {
		assertHasValues(adapter, parameter);
		parameter = parameter.nested();
		type = parameter.getNestedParameterType();
	}

	if (typePredicate.test(annotation, type)) {
		if (adapter == null) {
			return true;
		}
		throw buildReactiveWrapperException(parameter);
	}

	return false;
}
 
private static boolean isAsyncVoidReturnType(MethodParameter returnType, @Nullable ReactiveAdapter adapter) {
	if (adapter != null && adapter.supportsEmpty()) {
		if (adapter.isNoValue()) {
			return true;
		}
		Type parameterType = returnType.getGenericParameterType();
		if (parameterType instanceof ParameterizedType) {
			ParameterizedType type = (ParameterizedType) parameterType;
			if (type.getActualTypeArguments().length == 1) {
				return Void.class.equals(type.getActualTypeArguments()[0]);
			}
		}
	}
	return false;
}
 
源代码24 项目: java-technology-stack   文件: ModelInitializer.java
private Mono<Void> handleResult(HandlerResult handlerResult, BindingContext bindingContext) {
	Object value = handlerResult.getReturnValue();
	if (value != null) {
		ResolvableType type = handlerResult.getReturnType();
		ReactiveAdapter adapter = this.adapterRegistry.getAdapter(type.resolve(), value);
		if (isAsyncVoidType(type, adapter)) {
			return Mono.from(adapter.toPublisher(value));
		}
		String name = getAttributeName(handlerResult.getReturnTypeSource());
		bindingContext.getModel().asMap().putIfAbsent(name, value);
	}
	return Mono.empty();
}
 
@Override
public Mono<Object> resolveArgument(
		MethodParameter parameter, BindingContext context, ServerWebExchange exchange) {

	Mono<WebSession> session = exchange.getSession();
	ReactiveAdapter adapter = getAdapterRegistry().getAdapter(parameter.getParameterType());
	return (adapter != null ? Mono.just(adapter.fromPublisher(session)) : Mono.from(session));
}
 
@Override
public boolean supports(HandlerResult result) {
	Class<?> valueType = resolveReturnValueType(result);
	if (isSupportedType(valueType)) {
		return true;
	}
	ReactiveAdapter adapter = getAdapter(result);
	return adapter != null && !adapter.isNoValue() &&
			isSupportedType(result.getReturnType().getGeneric().toClass());
}
 
private ResolvableType getElementType(ReactiveAdapter adapter, ResolvableType genericType) {
	if (adapter.isNoValue()) {
		return ResolvableType.forClass(Void.class);
	}
	else if (genericType != ResolvableType.NONE) {
		return genericType;
	}
	else {
		return ResolvableType.forClass(Object.class);
	}
}
 
@Override
public Mono<Object> resolveArgument(
		MethodParameter parameter, BindingContext context, ServerWebExchange exchange) {

	Mono<Principal> principal = exchange.getPrincipal();
	ReactiveAdapter adapter = getAdapterRegistry().getAdapter(parameter.getParameterType());
	return (adapter != null ? Mono.just(adapter.fromPublisher(principal)) : Mono.from(principal));
}
 
/**
 * Evaluate the {@code Predicate} on the method parameter type or on
 * the generic type within a reactive type wrapper.
 */
protected boolean checkParameterType(MethodParameter parameter, Predicate<Class<?>> predicate) {
	Class<?> type = parameter.getParameterType();
	ReactiveAdapter adapter = getAdapterRegistry().getAdapter(type);
	if (adapter != null) {
		assertHasValues(adapter, parameter);
		type = parameter.nested().getNestedParameterType();
	}
	return predicate.test(type);
}
 
/**
 * Evaluate the {@code Predicate} on the method parameter type if it has the
 * given annotation, nesting within {@link java.util.Optional} if necessary,
 * but raise an {@code IllegalStateException} if the same matches the generic
 * type within a reactive type wrapper.
 */
protected <A extends Annotation> boolean checkAnnotatedParamNoReactiveWrapper(
		MethodParameter parameter, Class<A> annotationType, BiPredicate<A, Class<?>> typePredicate) {

	A annotation = parameter.getParameterAnnotation(annotationType);
	if (annotation == null) {
		return false;
	}

	parameter = parameter.nestedIfOptional();
	Class<?> type = parameter.getNestedParameterType();

	ReactiveAdapter adapter = getAdapterRegistry().getAdapter(type);
	if (adapter != null) {
		assertHasValues(adapter, parameter);
		parameter = parameter.nested();
		type = parameter.getNestedParameterType();
	}

	if (typePredicate.test(annotation, type)) {
		if (adapter == null) {
			return true;
		}
		throw buildReactiveWrapperException(parameter);
	}

	return false;
}
 
 类所在包
 同包方法