@ -32,6 +32,7 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException ;
import org.springframework.beans.BeansException ;
import org.springframework.beans.factory.BeanFactory ;
import org.springframework.beans.factory.BeanFactory ;
import org.springframework.beans.factory.BeanFactoryAware ;
import org.springframework.beans.factory.BeanFactoryUtils ;
import org.springframework.beans.factory.BeanFactoryUtils ;
import org.springframework.beans.factory.DisposableBean ;
import org.springframework.beans.factory.DisposableBean ;
import org.springframework.beans.factory.InitializingBean ;
import org.springframework.beans.factory.InitializingBean ;
@ -39,11 +40,7 @@ import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException ;
import org.springframework.beans.factory.NoSuchBeanDefinitionException ;
import org.springframework.beans.factory.ObjectProvider ;
import org.springframework.beans.factory.ObjectProvider ;
import org.springframework.beans.factory.annotation.Autowired ;
import org.springframework.beans.factory.annotation.Autowired ;
import org.springframework.beans.factory.config.BeanDefinition ;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor ;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory ;
import org.springframework.beans.factory.support.BeanDefinitionRegistry ;
import org.springframework.beans.factory.support.BeanDefinitionRegistry ;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor ;
import org.springframework.beans.factory.support.RootBeanDefinition ;
import org.springframework.beans.factory.support.RootBeanDefinition ;
import org.springframework.boot.autoconfigure.AutoConfigureAfter ;
import org.springframework.boot.autoconfigure.AutoConfigureAfter ;
import org.springframework.boot.autoconfigure.AutoConfigureOrder ;
import org.springframework.boot.autoconfigure.AutoConfigureOrder ;
@ -68,14 +65,14 @@ import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration ;
import org.springframework.context.annotation.Configuration ;
import org.springframework.context.annotation.ConfigurationCondition ;
import org.springframework.context.annotation.ConfigurationCondition ;
import org.springframework.context.annotation.Import ;
import org.springframework.context.annotation.Import ;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar ;
import org.springframework.context.annotation.Primary ;
import org.springframework.context.annotation.Primary ;
import org.springframework.context.annotation.Role ;
import org.springframework.core.Ordered ;
import org.springframework.core.Ordered ;
import org.springframework.core.annotation.Order ;
import org.springframework.core.convert.converter.Converter ;
import org.springframework.core.convert.converter.Converter ;
import org.springframework.core.convert.converter.GenericConverter ;
import org.springframework.core.convert.converter.GenericConverter ;
import org.springframework.core.io.Resource ;
import org.springframework.core.io.Resource ;
import org.springframework.core.type.AnnotatedTypeMetadata ;
import org.springframework.core.type.AnnotatedTypeMetadata ;
import org.springframework.core.type.AnnotationMetadata ;
import org.springframework.format.Formatter ;
import org.springframework.format.Formatter ;
import org.springframework.format.FormatterRegistry ;
import org.springframework.format.FormatterRegistry ;
import org.springframework.format.datetime.DateFormatter ;
import org.springframework.format.datetime.DateFormatter ;
@ -163,12 +160,6 @@ public class WebMvcAutoConfiguration {
public static final String SKIP_PATH_EXTENSION_CONTENT_NEGOTIATION_ATTRIBUTE = PathExtensionContentNegotiationStrategy . class
public static final String SKIP_PATH_EXTENSION_CONTENT_NEGOTIATION_ATTRIBUTE = PathExtensionContentNegotiationStrategy . class
. getName ( ) + ".SKIP" ;
. getName ( ) + ".SKIP" ;
@Bean
@Role ( BeanDefinition . ROLE_INFRASTRUCTURE )
public static MvcValidatorPostProcessor mvcValidatorAliasPostProcessor ( ) {
return new MvcValidatorPostProcessor ( ) ;
}
@Bean
@Bean
@ConditionalOnMissingBean ( HiddenHttpMethodFilter . class )
@ConditionalOnMissingBean ( HiddenHttpMethodFilter . class )
public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter ( ) {
public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter ( ) {
@ -185,7 +176,7 @@ public class WebMvcAutoConfiguration {
// Defined as a nested config to ensure WebMvcConfigurerAdapter is not read when not
// Defined as a nested config to ensure WebMvcConfigurerAdapter is not read when not
// on the classpath
// on the classpath
@Configuration
@Configuration
@Import ( EnableWebMvcConfiguration . class )
@Import ( { EnableWebMvcConfiguration . class , MvcValidatorRegistrar . class } )
@EnableConfigurationProperties ( { WebMvcProperties . class , ResourceProperties . class } )
@EnableConfigurationProperties ( { WebMvcProperties . class , ResourceProperties . class } )
public static class WebMvcAutoConfigurationAdapter extends WebMvcConfigurerAdapter {
public static class WebMvcAutoConfigurationAdapter extends WebMvcConfigurerAdapter {
@ -642,7 +633,7 @@ public class WebMvcAutoConfiguration {
/ * *
/ * *
* Condition used to disable the default MVC validator registration . The
* Condition used to disable the default MVC validator registration . The
* { @link MvcValidator PostProcessor} is used to configure the { @code mvcValidator }
* { @link MvcValidator Registrar} is actually used to register the { @code mvcValidator }
* bean .
* bean .
* /
* /
static class DisableMvcValidatorCondition implements ConfigurationCondition {
static class DisableMvcValidatorCondition implements ConfigurationCondition {
@ -660,8 +651,8 @@ public class WebMvcAutoConfiguration {
}
}
/ * *
/ * *
* { @link BeanFactoryPostProcesso r} to deal with the MVC validator bean registration .
* { @link ImportBeanDefinitionRegistra r} to deal with the MVC validator bean
* Applies the following rules :
* registration. Applies the following rules :
* < ul >
* < ul >
* < li > With no validators - Uses standard
* < li > With no validators - Uses standard
* { @link WebMvcConfigurationSupport # mvcValidator ( ) } logic . < / li >
* { @link WebMvcConfigurationSupport # mvcValidator ( ) } logic . < / li >
@ -670,43 +661,45 @@ public class WebMvcAutoConfiguration {
* defined . < / li >
* defined . < / li >
* < / ul >
* < / ul >
* /
* /
@Order ( Ordered . LOWEST_PRECEDENCE )
static class MvcValidatorRegistrar
static class MvcValidatorPostProcessor
implements ImportBeanDefinitionRegistrar , BeanFactoryAware {
implements BeanDefinitionRegistryPostProcessor {
private static final String JSR303_VALIDATOR_CLASS = "javax.validation.Validator" ;
private static final String JSR303_VALIDATOR_CLASS = "javax.validation.Validator" ;
private BeanFactory beanFactory ;
@Override
@Override
public void postProcessBeanDefinitionRegistry ( BeanDefinitionRegistry registry )
public void setBeanFactory ( BeanFactory beanFactory ) throws BeansException {
throws BeansException {
this . beanFactory = beanFactory ;
if ( registry instanceof ListableBeanFactory ) {
postProcess ( registry , ( ListableBeanFactory ) registry ) ;
}
}
}
@Override
@Override
public void postProcessBeanFactory ( ConfigurableListableBeanFactory beanFactory )
public void registerBeanDefinitions ( AnnotationMetadata importingClassMetadata ,
throws BeansException {
BeanDefinitionRegistry registry ) {
if ( this . beanFactory instanceof ListableBeanFactory ) {
registerOrAliasMvcValidator ( registry ,
( ListableBeanFactory ) this . beanFactory ) ;
}
}
}
private void postProcess ( BeanDefinitionRegistry registry ,
private void registerOrAliasMvcValidator ( BeanDefinitionRegistry registry ,
ListableBeanFactory beanFactory ) {
ListableBeanFactory beanFactory ) {
String [ ] validatorBeans = BeanFactoryUtils . beanNamesForTypeIncludingAncestors (
String [ ] validatorBeans = BeanFactoryUtils . beanNamesForTypeIncludingAncestors (
beanFactory , Validator . class , false , false ) ;
beanFactory , Validator . class , false , false ) ;
if ( validatorBeans . length = = 0 ) {
if ( validatorBeans . length = = 0 ) {
register MvcValidator( registry , beanFactory ) ;
register New MvcValidator( registry , beanFactory ) ;
}
}
else if ( validatorBeans . length = = 1 ) {
else if ( validatorBeans . length = = 1 ) {
registry . registerAlias ( validatorBeans [ 0 ] , "mvcValidator" ) ;
registry . registerAlias ( validatorBeans [ 0 ] , "mvcValidator" ) ;
}
}
else {
else {
if ( ! ObjectUtils . containsElement ( validatorBeans , "mvcValidator" ) ) {
if ( ! ObjectUtils . containsElement ( validatorBeans , "mvcValidator" ) ) {
register MvcValidator( registry , beanFactory ) ;
register New MvcValidator( registry , beanFactory ) ;
}
}
}
}
}
}
private void register MvcValidator( BeanDefinitionRegistry registry ,
private void register New MvcValidator( BeanDefinitionRegistry registry ,
ListableBeanFactory beanFactory ) {
ListableBeanFactory beanFactory ) {
RootBeanDefinition definition = new RootBeanDefinition ( ) ;
RootBeanDefinition definition = new RootBeanDefinition ( ) ;
definition . setBeanClass ( getClass ( ) ) ;
definition . setBeanClass ( getClass ( ) ) ;