Update information on WebApplicationContext hierarchy
Issue: SPR-16041
This commit is contained in:
parent
cd634633d8
commit
32d78e60b6
|
@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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.context.annotation.AnnotationConfigApplicationContext;
|
||||||
import org.springframework.http.server.reactive.ServletHttpHandlerAdapter;
|
import org.springframework.http.server.reactive.ServletHttpHandlerAdapter;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
import org.springframework.web.reactive.DispatcherHandler;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for {@link org.springframework.web.WebApplicationInitializer}
|
* {@link org.springframework.web.WebApplicationInitializer WebApplicationInitializer}
|
||||||
* implementations that register a {@link DispatcherHandler} configured with annotated
|
* to register a {@code DispatcherHandler}, wrapping it in a
|
||||||
* {@link org.springframework.context.annotation.Configuration @Configuration} classes in the
|
* {@link ServletHttpHandlerAdapter}, and use Java-based Spring configuration.
|
||||||
* servlet context, wrapping it in a {@link ServletHttpHandlerAdapter}.
|
|
||||||
*
|
*
|
||||||
* <p>Concrete implementations are required to implement {@link #getConfigClasses()}.
|
* <p>Concrete implementations are required to implement {@link #getConfigClasses()}.
|
||||||
* Further template and customization methods are provided by
|
* Further template and customization methods are provided by
|
||||||
|
@ -38,6 +36,7 @@ import org.springframework.web.reactive.DispatcherHandler;
|
||||||
public abstract class AbstractAnnotationConfigDispatcherHandlerInitializer
|
public abstract class AbstractAnnotationConfigDispatcherHandlerInitializer
|
||||||
extends AbstractDispatcherHandlerInitializer {
|
extends AbstractDispatcherHandlerInitializer {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
* <p>This implementation creates an {@link AnnotationConfigApplicationContext},
|
* <p>This implementation creates an {@link AnnotationConfigApplicationContext},
|
||||||
|
@ -45,19 +44,18 @@ public abstract class AbstractAnnotationConfigDispatcherHandlerInitializer
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected ApplicationContext createApplicationContext() {
|
protected ApplicationContext createApplicationContext() {
|
||||||
AnnotationConfigApplicationContext servletAppContext = new AnnotationConfigApplicationContext();
|
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||||
Class<?>[] configClasses = getConfigClasses();
|
Class<?>[] configClasses = getConfigClasses();
|
||||||
if (!ObjectUtils.isEmpty(configClasses)) {
|
if (!ObjectUtils.isEmpty(configClasses)) {
|
||||||
servletAppContext.register(configClasses);
|
context.register(configClasses);
|
||||||
}
|
}
|
||||||
return servletAppContext;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify {@link org.springframework.context.annotation.Configuration @Configuration}
|
* Specify {@code @Configuration} and/or {@code @Component} classes for
|
||||||
* and/or {@link org.springframework.stereotype.Component @Component} classes to be
|
* the {@linkplain #createApplicationContext() application context}.
|
||||||
* provided to the {@linkplain #createApplicationContext() application context}.
|
* @return the configuration for the application context
|
||||||
* @return the configuration classes for the dispatcher servlet application context
|
|
||||||
*/
|
*/
|
||||||
protected abstract Class<?>[] getConfigClasses();
|
protected abstract Class<?>[] getConfigClasses();
|
||||||
|
|
||||||
|
|
|
@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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}
|
* Base class for {@link org.springframework.web.WebApplicationInitializer}
|
||||||
* implementations that register a {@link DispatcherHandler} in the servlet context, wrapping it in
|
* implementations that register a {@link DispatcherHandler} in the servlet
|
||||||
* a {@link ServletHttpHandlerAdapter}.
|
* context, wrapping it in a {@link ServletHttpHandlerAdapter}.
|
||||||
*
|
*
|
||||||
* <p>Concrete implementations are required to implement
|
* <p>Most applications should consider extending the Spring Java config, sub-class
|
||||||
* {@link #createApplicationContext()}, which gets invoked from
|
* {@link AbstractAnnotationConfigDispatcherHandlerInitializer}.
|
||||||
* {@link #registerDispatcherHandler(ServletContext)}. Further customization can be achieved by
|
|
||||||
* overriding {@link #customizeRegistration(ServletRegistration.Dynamic)}.
|
|
||||||
*
|
*
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @since 5.0
|
* @since 5.0
|
||||||
|
* @see AbstractServletHttpHandlerAdapterInitializer
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractDispatcherHandlerInitializer implements WebApplicationInitializer {
|
public abstract class AbstractDispatcherHandlerInitializer implements WebApplicationInitializer {
|
||||||
|
|
||||||
|
|
|
@ -27,16 +27,15 @@ import org.springframework.web.WebApplicationInitializer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for {@link 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.
|
||||||
*
|
*
|
||||||
* <p>Concrete implementations are required to implement
|
* <p>See {@link AbstractDispatcherHandlerInitializer} if registering a
|
||||||
* {@link #createHttpHandler()}, as well as {@link #getServletMappings()},
|
* {@link org.springframework.web.reactive.DispatcherHandler DispatcherHandler}.
|
||||||
* both of which get invoked from {@link #registerHandlerAdapter(ServletContext)}.
|
|
||||||
* Further customization can be achieved by overriding
|
|
||||||
* {@link #customizeRegistration(ServletRegistration.Dynamic)}.
|
|
||||||
*
|
*
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @since 5.0
|
* @since 5.0
|
||||||
|
* @see AbstractDispatcherHandlerInitializer
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractServletHttpHandlerAdapterInitializer implements WebApplicationInitializer {
|
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");
|
Assert.hasLength(servletName, "getServletName() must not return empty or null");
|
||||||
|
|
||||||
HttpHandler httpHandler = createHttpHandler();
|
HttpHandler httpHandler = createHttpHandler();
|
||||||
Assert.notNull(httpHandler,
|
Assert.notNull(httpHandler, "createHttpHandler() did not return a HttpHandler" +
|
||||||
"createHttpHandler() did not return a HttpHandler for servlet [" + servletName + "]");
|
"for servlet [" + servletName + "]");
|
||||||
|
|
||||||
ServletHttpHandlerAdapter servlet = createServlet(httpHandler);
|
ServletHttpHandlerAdapter servlet = createServlet(httpHandler);
|
||||||
Assert.notNull(servlet,
|
Assert.notNull(servlet, "createHttpHandler() did not return a ServletHttpHandlerAdapter " +
|
||||||
"createHttpHandler() did not return a ServletHttpHandlerAdapter for servlet [" + servletName + "]");
|
"for servlet [" + servletName + "]");
|
||||||
|
|
||||||
ServletRegistration.Dynamic registration = servletContext.addServlet(servletName, servlet);
|
ServletRegistration.Dynamic registration = servletContext.addServlet(servletName, servlet);
|
||||||
Assert.notNull(registration,
|
Assert.notNull(registration,
|
||||||
|
@ -102,8 +101,8 @@ public abstract class AbstractServletHttpHandlerAdapterInitializer implements We
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a {@link ServletHttpHandlerAdapter} with the specified .
|
* Create a {@link ServletHttpHandlerAdapter} with the specified .
|
||||||
* <p>Default implementation returns a {@code ServletHttpHandlerAdapter} with the provided
|
* <p>Default implementation returns a {@code ServletHttpHandlerAdapter}
|
||||||
* {@code httpHandler}.
|
* with the provided {@code httpHandler}.
|
||||||
*/
|
*/
|
||||||
protected ServletHttpHandlerAdapter createServlet(HttpHandler httpHandler) {
|
protected ServletHttpHandlerAdapter createServlet(HttpHandler httpHandler) {
|
||||||
return new ServletHttpHandlerAdapter(httpHandler);
|
return new ServletHttpHandlerAdapter(httpHandler);
|
||||||
|
|
|
@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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;
|
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for {@link org.springframework.web.WebApplicationInitializer}
|
* {@link org.springframework.web.WebApplicationInitializer WebApplicationInitializer}
|
||||||
* implementations that register a
|
* to register a {@code DispatcherServlet} and use Java-based Spring configuration.
|
||||||
* {@link org.springframework.web.servlet.DispatcherServlet DispatcherServlet}
|
|
||||||
* configured with annotated classes, e.g. Spring's
|
|
||||||
* {@link org.springframework.context.annotation.Configuration @Configuration} classes.
|
|
||||||
*
|
*
|
||||||
* <p>Concrete implementations are required to implement {@link #getRootConfigClasses()}
|
* <p>Implementations are required to implement:
|
||||||
* and {@link #getServletConfigClasses()} as well as {@link #getServletMappings()}.
|
* <ul>
|
||||||
* Further template and customization methods are provided by
|
* <li>{@link #getRootConfigClasses()} -- for "root" application context (non-web
|
||||||
* {@link AbstractDispatcherServletInitializer}.
|
* infrastructure) configuration.
|
||||||
|
* <li>{@link #getServletConfigClasses()} -- for {@code DispatcherServlet}
|
||||||
|
* application context (Spring MVC infrastructure) configuration.
|
||||||
|
* </ul>
|
||||||
*
|
*
|
||||||
* <p>This is the preferred approach for applications that use Java-based
|
* <p>If an application context hierarchy is not required, applications may
|
||||||
* Spring configuration.
|
* return all configuration via {@link #getRootConfigClasses()} and return
|
||||||
|
* {@code null} from {@link #getServletConfigClasses()}.
|
||||||
*
|
*
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @author Chris Beams
|
* @author Chris Beams
|
||||||
|
@ -54,9 +55,9 @@ public abstract class AbstractAnnotationConfigDispatcherServletInitializer
|
||||||
protected WebApplicationContext createRootApplicationContext() {
|
protected WebApplicationContext createRootApplicationContext() {
|
||||||
Class<?>[] configClasses = getRootConfigClasses();
|
Class<?>[] configClasses = getRootConfigClasses();
|
||||||
if (!ObjectUtils.isEmpty(configClasses)) {
|
if (!ObjectUtils.isEmpty(configClasses)) {
|
||||||
AnnotationConfigWebApplicationContext rootAppContext = new AnnotationConfigWebApplicationContext();
|
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
|
||||||
rootAppContext.register(configClasses);
|
context.register(configClasses);
|
||||||
return rootAppContext;
|
return context;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return null;
|
return null;
|
||||||
|
@ -70,30 +71,27 @@ public abstract class AbstractAnnotationConfigDispatcherServletInitializer
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected WebApplicationContext createServletApplicationContext() {
|
protected WebApplicationContext createServletApplicationContext() {
|
||||||
AnnotationConfigWebApplicationContext servletAppContext = new AnnotationConfigWebApplicationContext();
|
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
|
||||||
Class<?>[] configClasses = getServletConfigClasses();
|
Class<?>[] configClasses = getServletConfigClasses();
|
||||||
if (!ObjectUtils.isEmpty(configClasses)) {
|
if (!ObjectUtils.isEmpty(configClasses)) {
|
||||||
servletAppContext.register(configClasses);
|
context.register(configClasses);
|
||||||
}
|
}
|
||||||
return servletAppContext;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify {@link org.springframework.context.annotation.Configuration @Configuration}
|
* Specify {@code @Configuration} and/or {@code @Component} classes for the
|
||||||
* and/or {@link org.springframework.stereotype.Component @Component} classes to be
|
* {@linkplain #createRootApplicationContext() root application context}.
|
||||||
* provided to the {@linkplain #createRootApplicationContext() root application context}.
|
* @return the configuration for the root application context, or {@code null}
|
||||||
* @return the configuration classes for the root application context, or {@code null}
|
|
||||||
* if creation and registration of a root context is not desired
|
* if creation and registration of a root context is not desired
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
protected abstract Class<?>[] getRootConfigClasses();
|
protected abstract Class<?>[] getRootConfigClasses();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify {@link org.springframework.context.annotation.Configuration @Configuration}
|
* Specify {@code @Configuration} and/or {@code @Component} classes for the
|
||||||
* and/or {@link org.springframework.stereotype.Component @Component} classes to be
|
* {@linkplain #createServletApplicationContext() Servlet application context}.
|
||||||
* provided to the {@linkplain #createServletApplicationContext() dispatcher servlet
|
* @return the configuration for the Servlet application context, or
|
||||||
* application context}.
|
|
||||||
* @return the configuration classes for the dispatcher servlet application context or
|
|
||||||
* {@code null} if all configuration is specified through root config classes.
|
* {@code null} if all configuration is specified through root config classes.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|
|
@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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}
|
* Base class for {@link org.springframework.web.WebApplicationInitializer}
|
||||||
* implementations that register a {@link DispatcherServlet} in the servlet context.
|
* implementations that register a {@link DispatcherServlet} in the servlet context.
|
||||||
*
|
*
|
||||||
* <p>Concrete implementations are required to implement
|
* <p>Most applications should consider extending the Spring Java config, sub-class
|
||||||
* {@link #createServletApplicationContext()}, as well as {@link #getServletMappings()},
|
* {@link AbstractAnnotationConfigDispatcherServletInitializer}.
|
||||||
* both of which get invoked from {@link #registerDispatcherServlet(ServletContext)}.
|
|
||||||
* Further customization can be achieved by overriding
|
|
||||||
* {@link #customizeRegistration(ServletRegistration.Dynamic)}.
|
|
||||||
*
|
|
||||||
* <p>Because this class extends from {@link AbstractContextLoaderInitializer}, concrete
|
|
||||||
* implementations are also required to implement {@link #createRootApplicationContext()}
|
|
||||||
* to set up a parent "<strong>root</strong>" application context. If a root context is
|
|
||||||
* not desired, implementations can simply return {@code null} in the
|
|
||||||
* {@code createRootApplicationContext()} implementation.
|
|
||||||
*
|
*
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @author Chris Beams
|
* @author Chris Beams
|
||||||
|
|
|
@ -346,8 +346,13 @@ server.addConnector(connector);
|
||||||
server.start();
|
server.start();
|
||||||
----
|
----
|
||||||
|
|
||||||
You can also deploy as a WAR to any Servlet 3.1 container by wrapping the handler with
|
[NOTE]
|
||||||
`ServletHttpHandlerAdapter` as a `Servlet`.
|
====
|
||||||
|
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.
|
||||||
|
====
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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:
|
And the `web.xml` equivalent:
|
||||||
|
|
||||||
[source,xml,indent=0]
|
[source,xml,indent=0]
|
||||||
|
@ -195,6 +201,13 @@ And the `web.xml` equivalent:
|
||||||
</web-app>
|
</web-app>
|
||||||
----
|
----
|
||||||
|
|
||||||
|
[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]]
|
[[mvc-servlet-special-bean-types]]
|
||||||
|
|
Loading…
Reference in New Issue