From 32d78e60b6bf19a66865478b86c69eb6ff49c8df Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 17 Oct 2017 21:49:57 -0400 Subject: [PATCH] Update information on WebApplicationContext hierarchy Issue: SPR-16041 --- ...ionConfigDispatcherHandlerInitializer.java | 24 ++++----- .../AbstractDispatcherHandlerInitializer.java | 13 +++-- ...tServletHttpHandlerAdapterInitializer.java | 23 ++++---- ...ionConfigDispatcherServletInitializer.java | 52 +++++++++---------- .../AbstractDispatcherServletInitializer.java | 15 ++---- src/docs/asciidoc/web/webflux.adoc | 9 +++- src/docs/asciidoc/web/webmvc.adoc | 13 +++++ 7 files changed, 76 insertions(+), 73 deletions(-) diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/support/AbstractAnnotationConfigDispatcherHandlerInitializer.java b/spring-webflux/src/main/java/org/springframework/web/reactive/support/AbstractAnnotationConfigDispatcherHandlerInitializer.java index 59339ddfc5..94962a4933 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/support/AbstractAnnotationConfigDispatcherHandlerInitializer.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/support/AbstractAnnotationConfigDispatcherHandlerInitializer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -20,13 +20,11 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.http.server.reactive.ServletHttpHandlerAdapter; import org.springframework.util.ObjectUtils; -import org.springframework.web.reactive.DispatcherHandler; /** - * Base class for {@link org.springframework.web.WebApplicationInitializer} - * implementations that register a {@link DispatcherHandler} configured with annotated - * {@link org.springframework.context.annotation.Configuration @Configuration} classes in the - * servlet context, wrapping it in a {@link ServletHttpHandlerAdapter}. + * {@link org.springframework.web.WebApplicationInitializer WebApplicationInitializer} + * to register a {@code DispatcherHandler}, wrapping it in a + * {@link ServletHttpHandlerAdapter}, and use Java-based Spring configuration. * *

Concrete implementations are required to implement {@link #getConfigClasses()}. * Further template and customization methods are provided by @@ -38,6 +36,7 @@ import org.springframework.web.reactive.DispatcherHandler; public abstract class AbstractAnnotationConfigDispatcherHandlerInitializer extends AbstractDispatcherHandlerInitializer { + /** * {@inheritDoc} *

This implementation creates an {@link AnnotationConfigApplicationContext}, @@ -45,19 +44,18 @@ public abstract class AbstractAnnotationConfigDispatcherHandlerInitializer */ @Override protected ApplicationContext createApplicationContext() { - AnnotationConfigApplicationContext servletAppContext = new AnnotationConfigApplicationContext(); + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); Class[] configClasses = getConfigClasses(); if (!ObjectUtils.isEmpty(configClasses)) { - servletAppContext.register(configClasses); + context.register(configClasses); } - return servletAppContext; + return context; } /** - * Specify {@link org.springframework.context.annotation.Configuration @Configuration} - * and/or {@link org.springframework.stereotype.Component @Component} classes to be - * provided to the {@linkplain #createApplicationContext() application context}. - * @return the configuration classes for the dispatcher servlet application context + * Specify {@code @Configuration} and/or {@code @Component} classes for + * the {@linkplain #createApplicationContext() application context}. + * @return the configuration for the application context */ protected abstract Class[] getConfigClasses(); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/support/AbstractDispatcherHandlerInitializer.java b/spring-webflux/src/main/java/org/springframework/web/reactive/support/AbstractDispatcherHandlerInitializer.java index 657a0be183..ffc368a4cf 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/support/AbstractDispatcherHandlerInitializer.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/support/AbstractDispatcherHandlerInitializer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -34,16 +34,15 @@ import org.springframework.web.server.adapter.HttpWebHandlerAdapter; /** * Base class for {@link org.springframework.web.WebApplicationInitializer} - * implementations that register a {@link DispatcherHandler} in the servlet context, wrapping it in - * a {@link ServletHttpHandlerAdapter}. + * implementations that register a {@link DispatcherHandler} in the servlet + * context, wrapping it in a {@link ServletHttpHandlerAdapter}. * - *

Concrete implementations are required to implement - * {@link #createApplicationContext()}, which gets invoked from - * {@link #registerDispatcherHandler(ServletContext)}. Further customization can be achieved by - * overriding {@link #customizeRegistration(ServletRegistration.Dynamic)}. + *

Most applications should consider extending the Spring Java config, sub-class + * {@link AbstractAnnotationConfigDispatcherHandlerInitializer}. * * @author Arjen Poutsma * @since 5.0 + * @see AbstractServletHttpHandlerAdapterInitializer */ public abstract class AbstractDispatcherHandlerInitializer implements WebApplicationInitializer { diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/support/AbstractServletHttpHandlerAdapterInitializer.java b/spring-webflux/src/main/java/org/springframework/web/reactive/support/AbstractServletHttpHandlerAdapterInitializer.java index 2dedbfc1b5..7dc833d3e0 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/support/AbstractServletHttpHandlerAdapterInitializer.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/support/AbstractServletHttpHandlerAdapterInitializer.java @@ -27,16 +27,15 @@ import org.springframework.web.WebApplicationInitializer; /** * Base class for {@link org.springframework.web.WebApplicationInitializer} - * implementations that register a {@link ServletHttpHandlerAdapter} in the servlet context. + * implementations that register a {@link ServletHttpHandlerAdapter} in the + * servlet context. * - *

Concrete implementations are required to implement - * {@link #createHttpHandler()}, as well as {@link #getServletMappings()}, - * both of which get invoked from {@link #registerHandlerAdapter(ServletContext)}. - * Further customization can be achieved by overriding - * {@link #customizeRegistration(ServletRegistration.Dynamic)}. + *

See {@link AbstractDispatcherHandlerInitializer} if registering a + * {@link org.springframework.web.reactive.DispatcherHandler DispatcherHandler}. * * @author Arjen Poutsma * @since 5.0 + * @see AbstractDispatcherHandlerInitializer */ public abstract class AbstractServletHttpHandlerAdapterInitializer implements WebApplicationInitializer { @@ -67,12 +66,12 @@ public abstract class AbstractServletHttpHandlerAdapterInitializer implements We Assert.hasLength(servletName, "getServletName() must not return empty or null"); HttpHandler httpHandler = createHttpHandler(); - Assert.notNull(httpHandler, - "createHttpHandler() did not return a HttpHandler for servlet [" + servletName + "]"); + Assert.notNull(httpHandler, "createHttpHandler() did not return a HttpHandler" + + "for servlet [" + servletName + "]"); ServletHttpHandlerAdapter servlet = createServlet(httpHandler); - Assert.notNull(servlet, - "createHttpHandler() did not return a ServletHttpHandlerAdapter for servlet [" + servletName + "]"); + Assert.notNull(servlet, "createHttpHandler() did not return a ServletHttpHandlerAdapter " + + "for servlet [" + servletName + "]"); ServletRegistration.Dynamic registration = servletContext.addServlet(servletName, servlet); Assert.notNull(registration, @@ -102,8 +101,8 @@ public abstract class AbstractServletHttpHandlerAdapterInitializer implements We /** * Create a {@link ServletHttpHandlerAdapter} with the specified . - *

Default implementation returns a {@code ServletHttpHandlerAdapter} with the provided - * {@code httpHandler}. + *

Default implementation returns a {@code ServletHttpHandlerAdapter} + * with the provided {@code httpHandler}. */ protected ServletHttpHandlerAdapter createServlet(HttpHandler httpHandler) { return new ServletHttpHandlerAdapter(httpHandler); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/AbstractAnnotationConfigDispatcherServletInitializer.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/AbstractAnnotationConfigDispatcherServletInitializer.java index 0848544619..3bcbe67817 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/AbstractAnnotationConfigDispatcherServletInitializer.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/AbstractAnnotationConfigDispatcherServletInitializer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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,19 +22,20 @@ import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; /** - * Base class for {@link org.springframework.web.WebApplicationInitializer} - * implementations that register a - * {@link org.springframework.web.servlet.DispatcherServlet DispatcherServlet} - * configured with annotated classes, e.g. Spring's - * {@link org.springframework.context.annotation.Configuration @Configuration} classes. + * {@link org.springframework.web.WebApplicationInitializer WebApplicationInitializer} + * to register a {@code DispatcherServlet} and use Java-based Spring configuration. * - *

Concrete implementations are required to implement {@link #getRootConfigClasses()} - * and {@link #getServletConfigClasses()} as well as {@link #getServletMappings()}. - * Further template and customization methods are provided by - * {@link AbstractDispatcherServletInitializer}. + *

Implementations are required to implement: + *

* - *

This is the preferred approach for applications that use Java-based - * Spring configuration. + *

If an application context hierarchy is not required, applications may + * return all configuration via {@link #getRootConfigClasses()} and return + * {@code null} from {@link #getServletConfigClasses()}. * * @author Arjen Poutsma * @author Chris Beams @@ -54,9 +55,9 @@ public abstract class AbstractAnnotationConfigDispatcherServletInitializer protected WebApplicationContext createRootApplicationContext() { Class[] configClasses = getRootConfigClasses(); if (!ObjectUtils.isEmpty(configClasses)) { - AnnotationConfigWebApplicationContext rootAppContext = new AnnotationConfigWebApplicationContext(); - rootAppContext.register(configClasses); - return rootAppContext; + AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); + context.register(configClasses); + return context; } else { return null; @@ -70,30 +71,27 @@ public abstract class AbstractAnnotationConfigDispatcherServletInitializer */ @Override protected WebApplicationContext createServletApplicationContext() { - AnnotationConfigWebApplicationContext servletAppContext = new AnnotationConfigWebApplicationContext(); + AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext(); Class[] configClasses = getServletConfigClasses(); if (!ObjectUtils.isEmpty(configClasses)) { - servletAppContext.register(configClasses); + context.register(configClasses); } - return servletAppContext; + return context; } /** - * Specify {@link org.springframework.context.annotation.Configuration @Configuration} - * and/or {@link org.springframework.stereotype.Component @Component} classes to be - * provided to the {@linkplain #createRootApplicationContext() root application context}. - * @return the configuration classes for the root application context, or {@code null} + * Specify {@code @Configuration} and/or {@code @Component} classes for the + * {@linkplain #createRootApplicationContext() root application context}. + * @return the configuration for the root application context, or {@code null} * if creation and registration of a root context is not desired */ @Nullable protected abstract Class[] getRootConfigClasses(); /** - * Specify {@link org.springframework.context.annotation.Configuration @Configuration} - * and/or {@link org.springframework.stereotype.Component @Component} classes to be - * provided to the {@linkplain #createServletApplicationContext() dispatcher servlet - * application context}. - * @return the configuration classes for the dispatcher servlet application context or + * Specify {@code @Configuration} and/or {@code @Component} classes for the + * {@linkplain #createServletApplicationContext() Servlet application context}. + * @return the configuration for the Servlet application context, or * {@code null} if all configuration is specified through root config classes. */ @Nullable diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/AbstractDispatcherServletInitializer.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/AbstractDispatcherServletInitializer.java index 1700d95765..e16494b61e 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/AbstractDispatcherServletInitializer.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/AbstractDispatcherServletInitializer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2017 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. @@ -40,17 +40,8 @@ import org.springframework.web.servlet.FrameworkServlet; * Base class for {@link org.springframework.web.WebApplicationInitializer} * implementations that register a {@link DispatcherServlet} in the servlet context. * - *

Concrete implementations are required to implement - * {@link #createServletApplicationContext()}, as well as {@link #getServletMappings()}, - * both of which get invoked from {@link #registerDispatcherServlet(ServletContext)}. - * Further customization can be achieved by overriding - * {@link #customizeRegistration(ServletRegistration.Dynamic)}. - * - *

Because this class extends from {@link AbstractContextLoaderInitializer}, concrete - * implementations are also required to implement {@link #createRootApplicationContext()} - * to set up a parent "root" application context. If a root context is - * not desired, implementations can simply return {@code null} in the - * {@code createRootApplicationContext()} implementation. + *

Most applications should consider extending the Spring Java config, sub-class + * {@link AbstractAnnotationConfigDispatcherServletInitializer}. * * @author Arjen Poutsma * @author Chris Beams diff --git a/src/docs/asciidoc/web/webflux.adoc b/src/docs/asciidoc/web/webflux.adoc index 2164abde7f..e2519befa2 100644 --- a/src/docs/asciidoc/web/webflux.adoc +++ b/src/docs/asciidoc/web/webflux.adoc @@ -346,8 +346,13 @@ server.addConnector(connector); server.start(); ---- -You can also deploy as a WAR to any Servlet 3.1 container by wrapping the handler with -`ServletHttpHandlerAdapter` as a `Servlet`. +[NOTE] +==== +To deploy as a WAR to a Servlet 3.1+ container, wrap `HttpHandler` with +`ServletHttpHandlerAdapter` and register that as a `Servlet`. Use +{api-spring-framework}/web/reactive/support/AbstractServletHttpHandlerAdapterInitializer.html[AbstractServletHttpHandlerAdapterInitializer] +to automate the required Servlet container configuration. +==== diff --git a/src/docs/asciidoc/web/webmvc.adoc b/src/docs/asciidoc/web/webmvc.adoc index 3773a0da52..b799d95bbf 100644 --- a/src/docs/asciidoc/web/webmvc.adoc +++ b/src/docs/asciidoc/web/webmvc.adoc @@ -161,6 +161,12 @@ Below is example configuration with a `WebApplicationContext` hierarchy: } ---- +[TIP] +==== +If an application context hierarchy is not required, applications may return all +configuration via `getRootConfigClasses()` and `null` from `getServletConfigClasses()`. +==== + And the `web.xml` equivalent: [source,xml,indent=0] @@ -195,6 +201,13 @@ And the `web.xml` equivalent: ---- +[TIP] +==== +If an application context hierarchy is not required, applications may configure a +"root" context only and leave the `contextConfigLocation` Servlet parameter empty. +==== + + [[mvc-servlet-special-bean-types]]