diff --git a/spring-web/src/main/java/org/springframework/web/server/adapter/AbstractReactiveWebInitializer.java b/spring-web/src/main/java/org/springframework/web/server/adapter/AbstractReactiveWebInitializer.java new file mode 100644 index 00000000000..d6c005aab81 --- /dev/null +++ b/spring-web/src/main/java/org/springframework/web/server/adapter/AbstractReactiveWebInitializer.java @@ -0,0 +1,96 @@ +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.web.server.adapter; + +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRegistration; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.http.server.reactive.HttpHandler; +import org.springframework.http.server.reactive.ServletHttpHandlerAdapter; +import org.springframework.util.Assert; +import org.springframework.web.WebApplicationInitializer; + +/** + * Base class for a {@link org.springframework.web.WebApplicationInitializer} + * that installs a Spring Reactive Web Application on a Servlet container. + * + *
Spring configuration is loaded and given to + * {@link WebHttpHandlerBuilder#applicationContext WebHttpHandlerBuilder} + * which scans the context looking for specific beans and creates a reactive + * {@link HttpHandler}. The resulting handler is installed as a Servlet through + * the {@link ServletHttpHandlerAdapter}. + * + * @author Rossen Stoyanchev + * @since 5.0.2 + */ +public abstract class AbstractReactiveWebInitializer implements WebApplicationInitializer { + + /** + * The default servlet name to use. See {@link #getServletName}. + */ + public static final String DEFAULT_SERVLET_NAME = "http-handler-adapter"; + + + @Override + public void onStartup(ServletContext servletContext) throws ServletException { + String servletName = getServletName(); + Assert.hasLength(servletName, "getServletName() must not return empty or null"); + + ApplicationContext applicationContext = createApplicationContext(); + Assert.notNull(applicationContext, "createApplicationContext() must not return null."); + + HttpHandler httpHandler = WebHttpHandlerBuilder.applicationContext(applicationContext).build(); + ServletHttpHandlerAdapter servlet = new ServletHttpHandlerAdapter(httpHandler); + + ServletRegistration.Dynamic registration = servletContext.addServlet(servletName, servlet); + Assert.notNull(registration, "Failed to register servlet '" + servletName + "'."); + + registration.setLoadOnStartup(1); + registration.addMapping("/"); + registration.setAsyncSupported(true); + } + + /** + * Return the name to use to register the {@link ServletHttpHandlerAdapter}. + *
By default this is {@link #DEFAULT_SERVLET_NAME}. + */ + protected String getServletName() { + return DEFAULT_SERVLET_NAME; + } + + /** + * Return the Spring configuration that contains application beans including + * the ones detected by {@link WebHttpHandlerBuilder#applicationContext}. + */ + protected ApplicationContext createApplicationContext() { + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); + Class>[] configClasses = getConfigClasses(); + Assert.notEmpty(configClasses, "No Spring configuration provided."); + return context; + } + + /** + * Specify {@link org.springframework.context.annotation.Configuration @Configuration} and/or + * {@link org.springframework.stereotype.Component @Component} classes that + * make up the application configuration. The config classes are given to + * {@linkplain #createApplicationContext()}. + */ + protected abstract Class>[] getConfigClasses(); + +} 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 94962a49337..ff9dafe9ef8 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 @@ -26,13 +26,12 @@ import org.springframework.util.ObjectUtils; * 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 - * {@link AbstractDispatcherHandlerInitializer}. - * * @author Arjen Poutsma - * @since 5.0 + * @deprecated in favor of + * {@link org.springframework.web.server.adapter.AbstractReactiveWebInitializer + * AbstractReactiveWebInitializer} */ +@Deprecated public abstract class AbstractAnnotationConfigDispatcherHandlerInitializer extends AbstractDispatcherHandlerInitializer { 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 ffc368a4cf6..3a798e91286 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 @@ -37,13 +37,13 @@ import org.springframework.web.server.adapter.HttpWebHandlerAdapter; * implementations that register a {@link DispatcherHandler} in the servlet * context, wrapping it in a {@link ServletHttpHandlerAdapter}. * - *
Most applications should consider extending the Spring Java config, sub-class - * {@link AbstractAnnotationConfigDispatcherHandlerInitializer}. - * * @author Arjen Poutsma * @since 5.0 - * @see AbstractServletHttpHandlerAdapterInitializer + * @deprecated in favor of + * {@link org.springframework.web.server.adapter.AbstractReactiveWebInitializer + * AbstractReactiveWebInitializer} */ +@Deprecated 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 7dc833d3e04..837491201c7 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 @@ -30,13 +30,13 @@ import org.springframework.web.WebApplicationInitializer; * implementations that register a {@link ServletHttpHandlerAdapter} in the * servlet context. * - *
See {@link AbstractDispatcherHandlerInitializer} if registering a - * {@link org.springframework.web.reactive.DispatcherHandler DispatcherHandler}. - * * @author Arjen Poutsma * @since 5.0 - * @see AbstractDispatcherHandlerInitializer + * @deprecated in favor of + * {@link org.springframework.web.server.adapter.AbstractReactiveWebInitializer + * AbstractReactiveWebInitializer} */ +@Deprecated public abstract class AbstractServletHttpHandlerAdapterInitializer implements WebApplicationInitializer { /** diff --git a/src/docs/asciidoc/web/webflux.adoc b/src/docs/asciidoc/web/webflux.adoc index 40c4d9fa6d9..2d1baadce4c 100644 --- a/src/docs/asciidoc/web/webflux.adoc +++ b/src/docs/asciidoc/web/webflux.adoc @@ -361,9 +361,9 @@ server.start(); [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. +`ServletHttpHandlerAdapter` and register that as a `Servlet`. +This can be automated through the use of +{api-spring-framework}/web/server/adapter/AbstractReactiveWebInitializer.html[AbstractReactiveWebInitializer]. ====