From cd2fee035af8f235e8843b049878721dcab63703 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Thu, 3 Nov 2011 19:19:54 +0000 Subject: [PATCH] SPR-8783 Update javadoc of MVC's AnnotationDrivenBeanDefinitionParser --- .../AnnotationDrivenBeanDefinitionParser.java | 79 +++++++++++++------ ...ultServletHandlerBeanDefinitionParser.java | 7 +- .../web/servlet/config/MvcNamespaceUtils.java | 55 ++++++++----- .../config/ResourcesBeanDefinitionParser.java | 6 +- .../ViewControllerBeanDefinitionParser.java | 7 +- .../DelegatingWebMvcConfiguration.java | 7 +- .../WebMvcConfigurationSupport.java | 35 ++++---- 7 files changed, 115 insertions(+), 81 deletions(-) diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java index 99fc6a40165..0588f3f2859 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java @@ -27,7 +27,7 @@ import org.springframework.beans.factory.support.ManagedList; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.xml.BeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; -import org.springframework.core.convert.ConversionService; +import org.springframework.format.support.DefaultFormattingConversionService; import org.springframework.format.support.FormattingConversionServiceFactoryBean; import org.springframework.http.converter.ByteArrayHttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter; @@ -41,12 +41,21 @@ import org.springframework.http.converter.xml.SourceHttpMessageConverter; import org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter; import org.springframework.util.ClassUtils; import org.springframework.util.xml.DomUtils; -import org.springframework.validation.Validator; import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; +import org.springframework.web.HttpRequestHandler; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.support.ConfigurableWebBindingInitializer; import org.springframework.web.bind.support.WebArgumentResolver; +import org.springframework.web.servlet.HandlerAdapter; +import org.springframework.web.servlet.HandlerExceptionResolver; +import org.springframework.web.servlet.HandlerMapping; +import org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping; import org.springframework.web.servlet.handler.ConversionServiceExposingInterceptor; import org.springframework.web.servlet.handler.MappedInterceptor; +import org.springframework.web.servlet.mvc.Controller; +import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter; +import org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter; import org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver; import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; @@ -56,27 +65,52 @@ import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolv import org.w3c.dom.Element; /** - * {@link BeanDefinitionParser} that parses the {@code annotation-driven} element to configure a Spring MVC web - * application. + * A {@link BeanDefinitionParser} that provides the configuration for the + * {@code } MVC namespace element. * - *

Responsible for: - *

    - *
  1. Registering a {@code DefaultAnnotationHandlerMapping} bean for mapping HTTP Servlet Requests to {@code @Controller} methods - * using {@code @RequestMapping} annotations. - *
  2. Registering an {@code AnnotationMethodHandlerAdapter} bean for invoking annotated {@code @Controller} methods. - * Will configure the {@code HandlerAdapter}'s webBindingInitializer property for centrally configuring - * {@code @Controller} {@code DataBinder} instances: + *

    This class registers the following {@link HandlerMapping}s:

    *
      - *
    • Configures the conversionService if specified, otherwise defaults to a fresh {@link ConversionService} instance - * created by the default {@link FormattingConversionServiceFactoryBean}. - *
    • Configures the validator if specified, otherwise defaults to a fresh {@link Validator} instance created by the - * default {@link LocalValidatorFactoryBean} if the JSR-303 API is present on the classpath. - *
    • Configures standard {@link org.springframework.http.converter.HttpMessageConverter HttpMessageConverters}, - * including the {@link Jaxb2RootElementHttpMessageConverter} if JAXB2 is present on the classpath, and - * the {@link MappingJacksonHttpMessageConverter} if Jackson is present on the classpath. + *
    • {@link RequestMappingHandlerMapping} + * ordered at 0 for mapping requests to annotated controller methods. + *
    • {@link BeanNameUrlHandlerMapping} + * ordered at 2 to map URL paths to controller bean names. *
    - *
* + *

Note: Additional HandlerMappings may be registered + * as a result of using the {@code } or the + * {@code } MVC namespace elements. + * + *

This class registers the following {@link HandlerAdapter}s: + *

+ * + *

This class registers the following {@link HandlerExceptionResolver}s: + *

+ * + *

Both the {@link RequestMappingHandlerAdapter} and the + * {@link ExceptionHandlerExceptionResolver} are configured with default + * instances of the following kind, unless custom instances are provided: + *

+ * * @author Keith Donald * @author Juergen Hoeller * @author Arjen Poutsma @@ -178,11 +212,8 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser { parserContext.registerComponent(new BeanComponentDefinition(defaultExceptionResolver, defaultExceptionResolverName)); parserContext.registerComponent(new BeanComponentDefinition(mappedCsInterceptorDef, mappedInterceptorName)); - // Ensure BeanNameUrlHandlerMapping is not "turned off" (SPR-8289) - MvcNamespaceUtils.registerBeanNameUrlHandlerMapping(parserContext, source); - - // Ensure default HandlerAdapters are not "turned off" - MvcNamespaceUtils.registerDefaultHandlerAdapters(parserContext, source); + // Ensure BeanNameUrlHandlerMapping (SPR-8289) and default HandlerAdapters are not "turned off" + MvcNamespaceUtils.registerDefaultComponents(parserContext, source); parserContext.popAndRegisterContainingComponent(); diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/DefaultServletHandlerBeanDefinitionParser.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/DefaultServletHandlerBeanDefinitionParser.java index 3753d02e539..c85df515170 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/DefaultServletHandlerBeanDefinitionParser.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/DefaultServletHandlerBeanDefinitionParser.java @@ -69,11 +69,8 @@ class DefaultServletHandlerBeanDefinitionParser implements BeanDefinitionParser parserContext.getRegistry().registerBeanDefinition(handlerMappingBeanName, handlerMappingDef); parserContext.registerComponent(new BeanComponentDefinition(handlerMappingDef, handlerMappingBeanName)); - // Ensure BeanNameUrlHandlerMapping is not "turned off" (SPR-8289) - MvcNamespaceUtils.registerBeanNameUrlHandlerMapping(parserContext, source); - - // Register HttpRequestHandlerAdapter - MvcNamespaceUtils.registerDefaultHandlerAdapters(parserContext, source); + // Ensure BeanNameUrlHandlerMapping (SPR-8289) and default HandlerAdapters are not "turned off" + MvcNamespaceUtils.registerDefaultComponents(parserContext, source); return null; } diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcNamespaceUtils.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcNamespaceUtils.java index 96a74b87d9f..49db0579e4d 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcNamespaceUtils.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/MvcNamespaceUtils.java @@ -25,55 +25,68 @@ import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter; import org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter; /** - * Convenience methods for MVC namespace handlers. + * Convenience methods for use in MVC namespace BeanDefinitionParsers. * * @author Rossen Stoyanchev * @since 3.1 */ abstract class MvcNamespaceUtils { - private static final String BEAN_NAME_URL_HANDLER_MAPPING = - "org.springframework.web.servlet.handler.beanNameUrlHandlerMapping"; + private static final String BEAN_NAME_URL_HANDLER_MAPPING_BEAN_NAME = + BeanNameUrlHandlerMapping.class.getName(); - private static final String VIEW_CONTROLLER_HANDLER_ADAPTER = - "org.springframework.web.servlet.config.viewControllerHandlerAdapter"; + private static final String SIMPLE_CONTROLLER_HANDLER_ADAPTER_BEAN_NAME = + SimpleControllerHandlerAdapter.class.getName(); - private static final String HTTP_REQUEST_HANDLER_ADAPTER = - "org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter"; + private static final String HTTP_REQUEST_HANDLER_ADAPTER_BEAN_NAME = + HttpRequestHandlerAdapter.class.getName(); - public static void registerDefaultHandlerAdapters(ParserContext parserContext, Object source) { + public static void registerDefaultComponents(ParserContext parserContext, Object source) { + registerBeanNameUrlHandlerMapping(parserContext, source); registerHttpRequestHandlerAdapter(parserContext, source); registerSimpleControllerHandlerAdapter(parserContext, source); } - public static void registerBeanNameUrlHandlerMapping(ParserContext parserContext, Object source) { - if (!parserContext.getRegistry().containsBeanDefinition(BEAN_NAME_URL_HANDLER_MAPPING)){ + /** + * Registers an {@link HttpRequestHandlerAdapter} under a well-known + * name unless already registered. + */ + private static void registerBeanNameUrlHandlerMapping(ParserContext parserContext, Object source) { + if (!parserContext.getRegistry().containsBeanDefinition(BEAN_NAME_URL_HANDLER_MAPPING_BEAN_NAME)){ RootBeanDefinition beanNameMappingDef = new RootBeanDefinition(BeanNameUrlHandlerMapping.class); beanNameMappingDef.setSource(source); beanNameMappingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); - beanNameMappingDef.getPropertyValues().add("order", 2); // consistent with MvcConfiguration - parserContext.getRegistry().registerBeanDefinition(BEAN_NAME_URL_HANDLER_MAPPING, beanNameMappingDef); - parserContext.registerComponent(new BeanComponentDefinition(beanNameMappingDef, BEAN_NAME_URL_HANDLER_MAPPING)); + beanNameMappingDef.getPropertyValues().add("order", 2); // consistent with WebMvcConfigurationSupport + parserContext.getRegistry().registerBeanDefinition(BEAN_NAME_URL_HANDLER_MAPPING_BEAN_NAME, beanNameMappingDef); + parserContext.registerComponent(new BeanComponentDefinition(beanNameMappingDef, BEAN_NAME_URL_HANDLER_MAPPING_BEAN_NAME)); } } - public static void registerHttpRequestHandlerAdapter(ParserContext parserContext, Object source) { - if (!parserContext.getRegistry().containsBeanDefinition(HTTP_REQUEST_HANDLER_ADAPTER)) { + /** + * Registers an {@link HttpRequestHandlerAdapter} under a well-known + * name unless already registered. + */ + private static void registerHttpRequestHandlerAdapter(ParserContext parserContext, Object source) { + if (!parserContext.getRegistry().containsBeanDefinition(HTTP_REQUEST_HANDLER_ADAPTER_BEAN_NAME)) { RootBeanDefinition handlerAdapterDef = new RootBeanDefinition(HttpRequestHandlerAdapter.class); handlerAdapterDef.setSource(source); handlerAdapterDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); - parserContext.getRegistry().registerBeanDefinition(HTTP_REQUEST_HANDLER_ADAPTER, handlerAdapterDef); - parserContext.registerComponent(new BeanComponentDefinition(handlerAdapterDef, HTTP_REQUEST_HANDLER_ADAPTER)); + parserContext.getRegistry().registerBeanDefinition(HTTP_REQUEST_HANDLER_ADAPTER_BEAN_NAME, handlerAdapterDef); + parserContext.registerComponent(new BeanComponentDefinition(handlerAdapterDef, HTTP_REQUEST_HANDLER_ADAPTER_BEAN_NAME)); } } - public static void registerSimpleControllerHandlerAdapter(ParserContext parserContext, Object source) { - if (!parserContext.getRegistry().containsBeanDefinition(VIEW_CONTROLLER_HANDLER_ADAPTER)) { + /** + * Registers a {@link SimpleControllerHandlerAdapter} under a well-known + * name unless already registered. + */ + private static void registerSimpleControllerHandlerAdapter(ParserContext parserContext, Object source) { + if (!parserContext.getRegistry().containsBeanDefinition(SIMPLE_CONTROLLER_HANDLER_ADAPTER_BEAN_NAME)) { RootBeanDefinition handlerAdapterDef = new RootBeanDefinition(SimpleControllerHandlerAdapter.class); handlerAdapterDef.setSource(source); handlerAdapterDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); - parserContext.getRegistry().registerBeanDefinition(VIEW_CONTROLLER_HANDLER_ADAPTER, handlerAdapterDef); - parserContext.registerComponent(new BeanComponentDefinition(handlerAdapterDef, VIEW_CONTROLLER_HANDLER_ADAPTER)); + parserContext.getRegistry().registerBeanDefinition(SIMPLE_CONTROLLER_HANDLER_ADAPTER_BEAN_NAME, handlerAdapterDef); + parserContext.registerComponent(new BeanComponentDefinition(handlerAdapterDef, SIMPLE_CONTROLLER_HANDLER_ADAPTER_BEAN_NAME)); } } diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/ResourcesBeanDefinitionParser.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/ResourcesBeanDefinitionParser.java index e24f708f849..f2f05204c34 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/ResourcesBeanDefinitionParser.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/ResourcesBeanDefinitionParser.java @@ -73,11 +73,9 @@ class ResourcesBeanDefinitionParser implements BeanDefinitionParser { parserContext.getRegistry().registerBeanDefinition(beanName, handlerMappingDef); parserContext.registerComponent(new BeanComponentDefinition(handlerMappingDef, beanName)); - // Ensure BeanNameUrlHandlerMapping is not "turned off" (SPR-8289) - MvcNamespaceUtils.registerBeanNameUrlHandlerMapping(parserContext, source); - + // Ensure BeanNameUrlHandlerMapping (SPR-8289) and default HandlerAdapters are not "turned off" // Register HttpRequestHandlerAdapter - MvcNamespaceUtils.registerDefaultHandlerAdapters(parserContext, source); + MvcNamespaceUtils.registerDefaultComponents(parserContext, source); return null; } diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/ViewControllerBeanDefinitionParser.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/ViewControllerBeanDefinitionParser.java index 12432e92162..a3e423b7f0a 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/ViewControllerBeanDefinitionParser.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/ViewControllerBeanDefinitionParser.java @@ -49,11 +49,8 @@ class ViewControllerBeanDefinitionParser implements BeanDefinitionParser { // Register SimpleUrlHandlerMapping for view controllers BeanDefinition handlerMappingDef = registerHandlerMapping(parserContext, source); - // Ensure BeanNameUrlHandlerMapping is not "turned off" (SPR-8289) - MvcNamespaceUtils.registerBeanNameUrlHandlerMapping(parserContext, source); - - // Register SimpleControllerHandlerAdapter - MvcNamespaceUtils.registerDefaultHandlerAdapters(parserContext, source); + // Ensure BeanNameUrlHandlerMapping (SPR-8289) and default HandlerAdapters are not "turned off" + MvcNamespaceUtils.registerDefaultComponents(parserContext, source); // Create view controller bean definition RootBeanDefinition viewControllerDef = new RootBeanDefinition(ParameterizableViewController.class); diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.java index d9b77340792..5571532ed7d 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.java @@ -28,10 +28,9 @@ import org.springframework.web.method.support.HandlerMethodReturnValueHandler; import org.springframework.web.servlet.HandlerExceptionResolver; /** - * A sub-class of {@link WebMvcConfigurationSupport} that detects beans of - * type {@link WebMvcConfigurer}. Each {@link WebMvcConfigurer} is given a - * chance to customize the Spring MVC configuration provided through - * {@link WebMvcConfigurationSupport}. + * Extends {@link WebMvcConfigurationSupport} with the ability to detect beans + * of type {@link WebMvcConfigurer} and give them a chance to customize the + * provided configuration by delegating to them at the appropriate times. * * @author Rossen Stoyanchev * @since 3.1 diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java index 090a732d01b..6e47779b302 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java @@ -48,6 +48,7 @@ import org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter; import org.springframework.util.ClassUtils; import org.springframework.validation.Errors; import org.springframework.validation.Validator; +import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; import org.springframework.web.HttpRequestHandler; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; @@ -55,7 +56,6 @@ import org.springframework.web.bind.support.ConfigurableWebBindingInitializer; import org.springframework.web.context.ServletContextAware; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.HandlerMethodReturnValueHandler; -import org.springframework.web.servlet.DispatcherServlet; import org.springframework.web.servlet.HandlerAdapter; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.HandlerMapping; @@ -73,17 +73,13 @@ import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandl import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver; /** - * A base class that provides configuration for Spring MVC applications - * by registering Spring MVC infrastructure components detected by the - * {@link DispatcherServlet}. An application configuration class is not required - * to extend this class. A more likely place to start is to annotate - * an @{@link Configuration} class with @{@link EnableWebMvc} - * (see @{@link EnableWebMvc} and {@link WebMvcConfigurer} for details). - * - *

If the customization options available with use of @{@link EnableWebMvc} - * are not enough, consider extending directly from this class and override the - * appropriate methods. Remember to add @{@link Configuration} to your subclass - * and @{@link Bean} to any superclass @{@link Bean} methods you override. + * This is the main class providing the configuration behind the MVC Java config. + * It is typically imported by adding {@link EnableWebMvc @EnableWebMvc} to an + * application {@link Configuration @Configuration} class. An alternative more + * advanced option is to extend directly from this class and override methods as + * necessary remembering to add {@link Configuration @Configuration} to the + * subclass and {@link Bean @Bean} to overridden {@link Bean @Bean} methods. + * For more details see the Javadoc of {@link EnableWebMvc @EnableWebMvc}. * *

This class registers the following {@link HandlerMapping}s:

* * - *

Registers these other instances: + *

Both the {@link RequestMappingHandlerAdapter} and the + * {@link ExceptionHandlerExceptionResolver} are configured with default + * instances of the following kind, unless custom instances are provided: *

- * + * * @see EnableWebMvc * @see WebMvcConfigurer * @see WebMvcConfigurerAdapter