Polishing

This commit is contained in:
Juergen Hoeller 2016-08-18 10:50:56 +02:00
parent 78049d3d25
commit 96f1a0ecae
7 changed files with 137 additions and 133 deletions

View File

@ -433,7 +433,7 @@ public abstract class AbstractMessageBrokerConfiguration implements ApplicationC
catch (Throwable ex) {
throw new BeanInitializationException("Could not find default validator class", ex);
}
validator = (Validator) BeanUtils.instantiate(clazz);
validator = (Validator) BeanUtils.instantiateClass(clazz);
}
else {
validator = new Validator() {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -22,6 +22,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
@ -29,7 +30,7 @@ import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.HandlerExceptionResolver;
/**
* A sub-class of {@code WebMvcConfigurationSupport} that detects and delegates
* A subclass of {@code WebMvcConfigurationSupport} that detects and delegates
* to all beans of type {@link WebMvcConfigurer} allowing them to customize the
* configuration provided by {@code WebMvcConfigurationSupport}. This is the
* class actually imported by {@link EnableWebMvc @EnableWebMvc}.
@ -45,10 +46,9 @@ public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
@Autowired(required = false)
public void setConfigurers(List<WebMvcConfigurer> configurers) {
if (configurers == null || configurers.isEmpty()) {
return;
if (!CollectionUtils.isEmpty(configurers)) {
this.configurers.addWebMvcConfigurers(configurers);
}
this.configurers.addWebMvcConfigurers(configurers);
}
@ -117,16 +117,6 @@ public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
this.configurers.addFormatters(registry);
}
@Override
protected Validator getValidator() {
return this.configurers.getValidator();
}
@Override
protected MessageCodesResolver getMessageCodesResolver() {
return this.configurers.getMessageCodesResolver();
}
@Override
protected void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
this.configurers.configureHandlerExceptionResolvers(exceptionResolvers);
@ -137,4 +127,14 @@ public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
this.configurers.addCorsMappings(registry);
}
@Override
protected Validator getValidator() {
return this.configurers.getValidator();
}
@Override
protected MessageCodesResolver getMessageCodesResolver() {
return this.configurers.getMessageCodesResolver();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,6 +17,7 @@
package org.springframework.web.servlet.config.annotation;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
@ -229,6 +230,7 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
return this.servletContext;
}
/**
* Return a {@link RequestMappingHandlerMapping} ordered at 0 for mapping
* requests to annotated controllers.
@ -251,18 +253,20 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
if (configurer.isUseTrailingSlashMatch() != null) {
handlerMapping.setUseTrailingSlashMatch(configurer.isUseTrailingSlashMatch());
}
if (configurer.getPathMatcher() != null) {
handlerMapping.setPathMatcher(configurer.getPathMatcher());
UrlPathHelper pathHelper = configurer.getUrlPathHelper();
if (pathHelper != null) {
handlerMapping.setUrlPathHelper(pathHelper);
}
if (configurer.getUrlPathHelper() != null) {
handlerMapping.setUrlPathHelper(configurer.getUrlPathHelper());
PathMatcher pathMatcher = configurer.getPathMatcher();
if (pathMatcher != null) {
handlerMapping.setPathMatcher(pathMatcher);
}
return handlerMapping;
}
/**
* Protected method for plugging in a custom sub-class of
* Protected method for plugging in a custom subclass of
* {@link RequestMappingHandlerMapping}.
*/
protected RequestMappingHandlerMapping createRequestMappingHandlerMapping() {
@ -335,7 +339,7 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
}
protected Map<String, MediaType> getDefaultMediaTypes() {
Map<String, MediaType> map = new HashMap<String, MediaType>();
Map<String, MediaType> map = new HashMap<String, MediaType>(4);
if (romePresent) {
map.put("atom", MediaType.APPLICATION_ATOM_XML);
map.put("rss", MediaType.valueOf("application/rss+xml"));
@ -488,18 +492,14 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
adapter.setCustomReturnValueHandlers(returnValueHandlers);
if (jackson2Present) {
List<RequestBodyAdvice> requestBodyAdvices = new ArrayList<RequestBodyAdvice>();
requestBodyAdvices.add(new JsonViewRequestBodyAdvice());
adapter.setRequestBodyAdvice(requestBodyAdvices);
List<ResponseBodyAdvice<?>> responseBodyAdvices = new ArrayList<ResponseBodyAdvice<?>>();
responseBodyAdvices.add(new JsonViewResponseBodyAdvice());
adapter.setResponseBodyAdvice(responseBodyAdvices);
adapter.setRequestBodyAdvice(
Collections.<RequestBodyAdvice>singletonList(new JsonViewRequestBodyAdvice()));
adapter.setResponseBodyAdvice(
Collections.<ResponseBodyAdvice<?>>singletonList(new JsonViewResponseBodyAdvice()));
}
AsyncSupportConfigurer configurer = new AsyncSupportConfigurer();
configureAsyncSupport(configurer);
if (configurer.getTaskExecutor() != null) {
adapter.setTaskExecutor(configurer.getTaskExecutor());
}
@ -524,6 +524,20 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
return initializer;
}
/**
* Override this method to provide a custom {@link MessageCodesResolver}.
*/
protected MessageCodesResolver getMessageCodesResolver() {
return null;
}
/**
* Override this method to configure asynchronous request processing options.
* @see AsyncSupportConfigurer
*/
protected void configureAsyncSupport(AsyncSupportConfigurer configurer) {
}
/**
* Return a {@link FormattingConversionService} for use with annotated
* controller methods and the {@code spring:eval} JSP tag.
@ -536,6 +550,12 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
return conversionService;
}
/**
* Override this method to add custom {@link Converter}s and {@link Formatter}s.
*/
protected void addFormatters(FormatterRegistry registry) {
}
/**
* Return a global {@link Validator} instance for example for validating
* {@code @ModelAttribute} and {@code @RequestBody} method arguments.
@ -560,7 +580,7 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
catch (LinkageError ex) {
throw new BeanInitializationException("Could not load default validator class", ex);
}
validator = (Validator) BeanUtils.instantiate(clazz);
validator = (Validator) BeanUtils.instantiateClass(clazz);
}
else {
validator = new NoOpValidator();
@ -569,6 +589,13 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
return validator;
}
/**
* Override this method to provide a custom {@link Validator}.
*/
protected Validator getValidator() {
return null;
}
/**
* Return a global {@link PathMatcher} instance for path matching
* patterns in {@link HandlerMapping}s.
@ -595,26 +622,8 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
*/
@Bean
public UrlPathHelper mvcUrlPathHelper() {
if (getPathMatchConfigurer().getUrlPathHelper() != null) {
return getPathMatchConfigurer().getUrlPathHelper();
}
else {
return new UrlPathHelper();
}
}
/**
* Override this method to provide a custom {@link Validator}.
*/
protected Validator getValidator() {
return null;
}
/**
* Override this method to provide a custom {@link MessageCodesResolver}.
*/
protected MessageCodesResolver getMessageCodesResolver() {
return null;
UrlPathHelper pathHelper = getPathMatchConfigurer().getUrlPathHelper();
return (pathHelper != null ? pathHelper : new UrlPathHelper());
}
/**
@ -679,6 +688,14 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
}
/**
* Override this method to extend or modify the list of converters after it
* has been configured. This may be useful for example to allow default
* converters to be registered and then insert a custom converter through
* this method.
* @param converters the list of configured converters to extend.
* @since 4.1.3
*/
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
}
@ -719,19 +736,6 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
}
}
/**
* Override this method to add custom {@link Converter}s and {@link Formatter}s.
*/
protected void addFormatters(FormatterRegistry registry) {
}
/**
* Override this method to configure asynchronous request processing options.
* @see AsyncSupportConfigurer
*/
public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
}
/**
* Return an instance of {@link CompositeUriComponentsContributor} for use with
* {@link org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder}.
@ -774,11 +778,9 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
public HandlerExceptionResolver handlerExceptionResolver() {
List<HandlerExceptionResolver> exceptionResolvers = new ArrayList<HandlerExceptionResolver>();
configureHandlerExceptionResolvers(exceptionResolvers);
if (exceptionResolvers.isEmpty()) {
addDefaultHandlerExceptionResolvers(exceptionResolvers);
}
HandlerExceptionResolverComposite composite = new HandlerExceptionResolverComposite();
composite.setOrder(0);
composite.setExceptionResolvers(exceptionResolvers);

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -73,14 +73,6 @@ public interface WebMvcConfigurer {
*/
void extendMessageConverters(List<HttpMessageConverter<?>> converters);
/**
* Provide a custom {@link Validator} instead of the one created by default.
* The default implementation, assuming JSR-303 is on the classpath, is:
* {@link org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean}.
* Leave the return value as {@code null} to keep the default.
*/
Validator getValidator();
/**
* Configure content negotiation options.
*/
@ -144,13 +136,6 @@ public interface WebMvcConfigurer {
*/
void addInterceptors(InterceptorRegistry registry);
/**
* Provide a custom {@link MessageCodesResolver} for building message codes
* from data binding and validation error codes. Leave the return value as
* {@code null} to keep the default.
*/
MessageCodesResolver getMessageCodesResolver();
/**
* Configure simple automated controllers pre-configured with the response
* status code and/or a view to render the response body. This is useful in
@ -188,4 +173,19 @@ public interface WebMvcConfigurer {
*/
void addCorsMappings(CorsRegistry registry);
/**
* Provide a custom {@link Validator} instead of the one created by default.
* The default implementation, assuming JSR-303 is on the classpath, is:
* {@link org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean}.
* Leave the return value as {@code null} to keep the default.
*/
Validator getValidator();
/**
* Provide a custom {@link MessageCodesResolver} for building message codes
* from data binding and validation error codes. Leave the return value as
* {@code null} to keep the default.
*/
MessageCodesResolver getMessageCodesResolver();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -28,7 +28,7 @@ import org.springframework.web.servlet.HandlerExceptionResolver;
/**
* An implementation of {@link WebMvcConfigurer} with empty methods allowing
* sub-classes to override only the methods they're interested in.
* subclasses to override only the methods they're interested in.
*
* @author Rossen Stoyanchev
* @since 3.1
@ -59,15 +59,6 @@ public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
}
/**
* {@inheritDoc}
* <p>This implementation returns {@code null}
*/
@Override
public Validator getValidator() {
return null;
}
/**
* {@inheritDoc}
* <p>This implementation is empty.
@ -116,15 +107,6 @@ public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
}
/**
* {@inheritDoc}
* <p>This implementation is empty.
*/
@Override
public MessageCodesResolver getMessageCodesResolver() {
return null;
}
/**
* {@inheritDoc}
* <p>This implementation is empty.
@ -173,4 +155,22 @@ public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {
public void addCorsMappings(CorsRegistry registry) {
}
/**
* {@inheritDoc}
* <p>This implementation returns {@code null}.
*/
@Override
public Validator getValidator() {
return null;
}
/**
* {@inheritDoc}
* <p>This implementation returns {@code null}.
*/
@Override
public MessageCodesResolver getMessageCodesResolver() {
return null;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -21,6 +21,7 @@ import java.util.List;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
@ -28,7 +29,7 @@ import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.HandlerExceptionResolver;
/**
* An {@link WebMvcConfigurer} implementation that delegates to other {@link WebMvcConfigurer} instances.
* A {@link WebMvcConfigurer} that delegates to one or more others.
*
* @author Rossen Stoyanchev
* @since 3.1
@ -37,12 +38,14 @@ class WebMvcConfigurerComposite implements WebMvcConfigurer {
private final List<WebMvcConfigurer> delegates = new ArrayList<WebMvcConfigurer>();
public void addWebMvcConfigurers(List<WebMvcConfigurer> configurers) {
if (configurers != null) {
if (!CollectionUtils.isEmpty(configurers)) {
this.delegates.addAll(configurers);
}
}
@Override
public void addFormatters(FormatterRegistry registry) {
for (WebMvcConfigurer delegate : this.delegates) {
@ -141,6 +144,13 @@ class WebMvcConfigurerComposite implements WebMvcConfigurer {
}
}
@Override
public void addCorsMappings(CorsRegistry registry) {
for (WebMvcConfigurer delegate : this.delegates) {
delegate.addCorsMappings(registry);
}
}
@Override
public Validator getValidator() {
List<Validator> candidates = new ArrayList<Validator>();
@ -154,10 +164,15 @@ class WebMvcConfigurerComposite implements WebMvcConfigurer {
}
@Override
public void addCorsMappings(CorsRegistry registry) {
for (WebMvcConfigurer delegate : this.delegates) {
delegate.addCorsMappings(registry);
public MessageCodesResolver getMessageCodesResolver() {
List<MessageCodesResolver> candidates = new ArrayList<MessageCodesResolver>();
for (WebMvcConfigurer configurer : this.delegates) {
MessageCodesResolver messageCodesResolver = configurer.getMessageCodesResolver();
if (messageCodesResolver != null) {
candidates.add(messageCodesResolver);
}
}
return selectSingleInstance(candidates, MessageCodesResolver.class);
}
private <T> T selectSingleInstance(List<T> instances, Class<T> instanceType) {
@ -173,16 +188,4 @@ class WebMvcConfigurerComposite implements WebMvcConfigurer {
}
}
@Override
public MessageCodesResolver getMessageCodesResolver() {
List<MessageCodesResolver> candidates = new ArrayList<MessageCodesResolver>();
for (WebMvcConfigurer configurer : this.delegates) {
MessageCodesResolver messageCodesResolver = configurer.getMessageCodesResolver();
if (messageCodesResolver != null) {
candidates.add(messageCodesResolver);
}
}
return selectSingleInstance(candidates, MessageCodesResolver.class);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,7 +17,7 @@
package org.springframework.web.servlet.config.annotation;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.junit.Before;
@ -89,10 +89,10 @@ public class DelegatingWebMvcConfigurationTests {
delegatingConfig = new DelegatingWebMvcConfiguration();
}
@Test
public void requestMappingHandlerAdapter() throws Exception {
delegatingConfig.setConfigurers(Arrays.asList(webMvcConfigurer));
delegatingConfig.setConfigurers(Collections.singletonList(webMvcConfigurer));
RequestMappingHandlerAdapter adapter = delegatingConfig.requestMappingHandlerAdapter();
ConfigurableWebBindingInitializer initializer = (ConfigurableWebBindingInitializer) adapter.getWebBindingInitializer();
@ -141,7 +141,7 @@ public class DelegatingWebMvcConfigurationTests {
public void getCustomValidator() {
given(webMvcConfigurer.getValidator()).willReturn(new LocalValidatorFactoryBean());
delegatingConfig.setConfigurers(Arrays.asList(webMvcConfigurer));
delegatingConfig.setConfigurers(Collections.singletonList(webMvcConfigurer));
delegatingConfig.mvcValidator();
verify(webMvcConfigurer).getValidator();
@ -151,7 +151,7 @@ public class DelegatingWebMvcConfigurationTests {
public void getCustomMessageCodesResolver() {
given(webMvcConfigurer.getMessageCodesResolver()).willReturn(new DefaultMessageCodesResolver());
delegatingConfig.setConfigurers(Arrays.asList(webMvcConfigurer));
delegatingConfig.setConfigurers(Collections.singletonList(webMvcConfigurer));
delegatingConfig.getMessageCodesResolver();
verify(webMvcConfigurer).getMessageCodesResolver();
@ -159,8 +159,7 @@ public class DelegatingWebMvcConfigurationTests {
@Test
public void handlerExceptionResolver() throws Exception {
delegatingConfig.setConfigurers(Arrays.asList(webMvcConfigurer));
delegatingConfig.setConfigurers(Collections.singletonList(webMvcConfigurer));
delegatingConfig.handlerExceptionResolver();
verify(webMvcConfigurer).configureMessageConverters(converters.capture());
@ -186,7 +185,7 @@ public class DelegatingWebMvcConfigurationTests {
delegatingConfig.setConfigurers(configurers);
HandlerExceptionResolverComposite composite =
(HandlerExceptionResolverComposite) delegatingConfig.handlerExceptionResolver();
(HandlerExceptionResolverComposite) delegatingConfig.handlerExceptionResolver();
assertEquals("Only one custom converter is expected", 1, composite.getExceptionResolvers().size());
}
@ -200,9 +199,9 @@ public class DelegatingWebMvcConfigurationTests {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.setUseRegisteredSuffixPatternMatch(true)
.setUseTrailingSlashMatch(false)
.setUrlPathHelper(pathHelper)
.setPathMatcher(pathMatcher);
.setUseTrailingSlashMatch(false)
.setUrlPathHelper(pathHelper)
.setPathMatcher(pathMatcher);
}
});
delegatingConfig.setConfigurers(configurers);