Add ConcurrentModel
This commit adds a Model implementation based on ConcurrentHashMap for use in Spring Web Reactive. Issue: SPR-14542
This commit is contained in:
@@ -23,8 +23,8 @@ import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.ui.ExtendedModelMap;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.ui.ConcurrentModel;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -42,7 +42,7 @@ public class HandlerResult {
|
||||
|
||||
private final ResolvableType returnType;
|
||||
|
||||
private final ModelMap model;
|
||||
private final Model model;
|
||||
|
||||
private Function<Throwable, Mono<HandlerResult>> exceptionHandler;
|
||||
|
||||
@@ -64,13 +64,13 @@ public class HandlerResult {
|
||||
* @param returnType the return value type
|
||||
* @param model the model used for request handling
|
||||
*/
|
||||
public HandlerResult(Object handler, Object returnValue, MethodParameter returnType, ModelMap model) {
|
||||
public HandlerResult(Object handler, Object returnValue, MethodParameter returnType, Model model) {
|
||||
Assert.notNull(handler, "'handler' is required");
|
||||
Assert.notNull(returnType, "'returnType' is required");
|
||||
this.handler = handler;
|
||||
this.returnValue = Optional.ofNullable(returnValue);
|
||||
this.returnType = ResolvableType.forMethodParameter(returnType);
|
||||
this.model = (model != null ? model : new ExtendedModelMap());
|
||||
this.model = (model != null ? model : new ConcurrentModel());
|
||||
}
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ public class HandlerResult {
|
||||
* Return the model used during request handling with attributes that may be
|
||||
* used to render HTML templates with.
|
||||
*/
|
||||
public ModelMap getModel() {
|
||||
public Model getModel() {
|
||||
return this.model;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,9 +15,8 @@
|
||||
*/
|
||||
package org.springframework.web.reactive.result.method;
|
||||
|
||||
import org.springframework.beans.TypeConverter;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.validation.support.BindingAwareModelMap;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.support.BindingAwareConcurrentModel;
|
||||
import org.springframework.web.bind.WebDataBinder;
|
||||
import org.springframework.web.bind.WebExchangeDataBinder;
|
||||
import org.springframework.web.bind.support.WebBindingInitializer;
|
||||
@@ -33,12 +32,10 @@ import org.springframework.web.server.ServerWebExchange;
|
||||
*/
|
||||
public class BindingContext {
|
||||
|
||||
private final ModelMap model = new BindingAwareModelMap();
|
||||
private final Model model = new BindingAwareConcurrentModel();
|
||||
|
||||
private final WebBindingInitializer initializer;
|
||||
|
||||
private final TypeConverter simpleValueTypeConverter;
|
||||
|
||||
|
||||
public BindingContext() {
|
||||
this(null);
|
||||
@@ -46,7 +43,6 @@ public class BindingContext {
|
||||
|
||||
public BindingContext(WebBindingInitializer initializer) {
|
||||
this.initializer = initializer;
|
||||
this.simpleValueTypeConverter = initTypeConverter(initializer);
|
||||
}
|
||||
|
||||
private static WebExchangeDataBinder initTypeConverter(WebBindingInitializer initializer) {
|
||||
@@ -61,7 +57,7 @@ public class BindingContext {
|
||||
/**
|
||||
* Return the default model.
|
||||
*/
|
||||
public ModelMap getModel() {
|
||||
public Model getModel() {
|
||||
return this.model;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ import org.springframework.core.DefaultParameterNameDiscoverer;
|
||||
import org.springframework.core.GenericTypeResolver;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.ParameterNameDiscoverer;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
@@ -101,7 +102,7 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
||||
return resolveArguments(exchange, bindingContext, providedArgs).then(args -> {
|
||||
try {
|
||||
Object value = doInvoke(args);
|
||||
ModelMap model = bindingContext.getModel();
|
||||
Model model = bindingContext.getModel();
|
||||
HandlerResult handlerResult = new HandlerResult(this, value, getReturnType(), model);
|
||||
return Mono.just(handlerResult);
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ import org.springframework.beans.factory.config.BeanExpressionContext;
|
||||
import org.springframework.beans.factory.config.BeanExpressionResolver;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.WebDataBinder;
|
||||
import org.springframework.web.bind.annotation.ValueConstants;
|
||||
import org.springframework.web.reactive.result.method.BindingContext;
|
||||
@@ -87,7 +87,7 @@ public abstract class AbstractNamedValueArgumentResolver implements HandlerMetho
|
||||
"Specified name must not resolve to null: [" + namedValueInfo.name + "]"));
|
||||
}
|
||||
|
||||
ModelMap model = bindingContext.getModel();
|
||||
Model model = bindingContext.getModel();
|
||||
|
||||
return resolveName(resolvedName.toString(), nestedParameter, exchange)
|
||||
.map(arg -> {
|
||||
@@ -186,7 +186,7 @@ public abstract class AbstractNamedValueArgumentResolver implements HandlerMetho
|
||||
}
|
||||
|
||||
private Mono<Object> getDefaultValue(NamedValueInfo namedValueInfo, MethodParameter parameter,
|
||||
BindingContext bindingContext, ModelMap model, ServerWebExchange exchange) {
|
||||
BindingContext bindingContext, Model model, ServerWebExchange exchange) {
|
||||
|
||||
Object value = null;
|
||||
try {
|
||||
@@ -263,7 +263,7 @@ public abstract class AbstractNamedValueArgumentResolver implements HandlerMetho
|
||||
*/
|
||||
@SuppressWarnings("UnusedParameters")
|
||||
protected void handleResolvedValue(Object arg, String name, MethodParameter parameter,
|
||||
ModelMap model, ServerWebExchange exchange) {
|
||||
Model model, ServerWebExchange exchange) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ import java.util.Optional;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.ValueConstants;
|
||||
@@ -93,7 +93,7 @@ public class PathVariableMethodArgumentResolver extends AbstractNamedValueSyncAr
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void handleResolvedValue(Object arg, String name, MethodParameter parameter,
|
||||
ModelMap model, ServerWebExchange exchange) {
|
||||
Model model, ServerWebExchange exchange) {
|
||||
|
||||
// TODO: View.PATH_VARIABLES ?
|
||||
}
|
||||
|
||||
@@ -329,7 +329,7 @@ public class RequestMappingHandlerAdapter implements HandlerAdapter, BeanFactory
|
||||
logger.debug("Invoking @ExceptionHandler method: " + invocable.getMethod());
|
||||
}
|
||||
invocable.setArgumentResolvers(getArgumentResolvers());
|
||||
bindingContext.getModel().clear();
|
||||
bindingContext.getModel().asMap().clear();
|
||||
return invocable.invoke(exchange, bindingContext, ex);
|
||||
}
|
||||
catch (Throwable invocationEx) {
|
||||
|
||||
@@ -206,7 +206,7 @@ public class ViewResolutionResultHandler extends AbstractHandlerResultHandler
|
||||
.defaultIfEmpty(result.getModel())
|
||||
.then(model -> getDefaultViewNameMono(exchange, result));
|
||||
}
|
||||
Map<String, ?> model = result.getModel();
|
||||
Map<String, ?> model = result.getModel().asMap();
|
||||
return viewMono.then(view -> {
|
||||
updateResponseStatus(result.getReturnTypeSource(), exchange);
|
||||
if (view instanceof View) {
|
||||
|
||||
@@ -49,7 +49,6 @@ import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest;
|
||||
import org.springframework.mock.http.server.reactive.test.MockServerHttpResponse;
|
||||
import org.springframework.ui.ExtendedModelMap;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.reactive.HandlerResult;
|
||||
@@ -80,7 +79,7 @@ public class ViewResolutionResultHandlerTests {
|
||||
|
||||
private ServerWebExchange exchange;
|
||||
|
||||
private ModelMap model = new ExtendedModelMap();
|
||||
private Model model = new ExtendedModelMap();
|
||||
|
||||
|
||||
@Before
|
||||
@@ -184,7 +183,7 @@ public class ViewResolutionResultHandlerTests {
|
||||
private void testDefaultViewName(Object returnValue, ResolvableType type)
|
||||
throws URISyntaxException {
|
||||
|
||||
ModelMap model = new ExtendedModelMap().addAttribute("id", "123");
|
||||
Model model = new ExtendedModelMap().addAttribute("id", "123");
|
||||
HandlerResult result = new HandlerResult(new Object(), returnValue, returnType(type), model);
|
||||
ViewResolutionResultHandler handler = createResultHandler(new TestViewResolver("account"));
|
||||
|
||||
@@ -290,7 +289,7 @@ public class ViewResolutionResultHandlerTests {
|
||||
private void testHandle(String path, ResolvableMethod resolvableMethod, Object returnValue,
|
||||
String responseBody, ViewResolver... resolvers) throws URISyntaxException {
|
||||
|
||||
ModelMap model = new ExtendedModelMap().addAttribute("id", "123");
|
||||
Model model = new ExtendedModelMap().addAttribute("id", "123");
|
||||
MethodParameter returnType = resolvableMethod.resolveReturnType();
|
||||
HandlerResult result = new HandlerResult(new Object(), returnValue, returnType, model);
|
||||
this.request.setUri(path);
|
||||
|
||||
Reference in New Issue
Block a user