Skip to content

Commit aa653b2

Browse files
committed
Add AbstractReactiveWebInitializer
This commit introduces a new AbstractReactiveWebInitializer in spring-web that relies on WebHttpHandlerBuilder to detect request processing infrastructure beans from an ApplicationContext. This eliminates the need to create a DispatcherHandler, since it is expected to be a Spring bean, and as a result the initializers in spring-webflux have been deprecated. Issue: SPR-16144
1 parent 1611ce7 commit aa653b2

File tree

5 files changed

+111
-16
lines changed

5 files changed

+111
-16
lines changed
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*
2+
* Copyright 2002-2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.web.server.adapter;
17+
18+
import javax.servlet.ServletContext;
19+
import javax.servlet.ServletException;
20+
import javax.servlet.ServletRegistration;
21+
22+
import org.springframework.context.ApplicationContext;
23+
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
24+
import org.springframework.http.server.reactive.HttpHandler;
25+
import org.springframework.http.server.reactive.ServletHttpHandlerAdapter;
26+
import org.springframework.util.Assert;
27+
import org.springframework.web.WebApplicationInitializer;
28+
29+
/**
30+
* Base class for a {@link org.springframework.web.WebApplicationInitializer}
31+
* that installs a Spring Reactive Web Application on a Servlet container.
32+
*
33+
* <p>Spring configuration is loaded and given to
34+
* {@link WebHttpHandlerBuilder#applicationContext WebHttpHandlerBuilder}
35+
* which scans the context looking for specific beans and creates a reactive
36+
* {@link HttpHandler}. The resulting handler is installed as a Servlet through
37+
* the {@link ServletHttpHandlerAdapter}.
38+
*
39+
* @author Rossen Stoyanchev
40+
* @since 5.0.2
41+
*/
42+
public abstract class AbstractReactiveWebInitializer implements WebApplicationInitializer {
43+
44+
/**
45+
* The default servlet name to use. See {@link #getServletName}.
46+
*/
47+
public static final String DEFAULT_SERVLET_NAME = "http-handler-adapter";
48+
49+
50+
@Override
51+
public void onStartup(ServletContext servletContext) throws ServletException {
52+
String servletName = getServletName();
53+
Assert.hasLength(servletName, "getServletName() must not return empty or null");
54+
55+
ApplicationContext applicationContext = createApplicationContext();
56+
Assert.notNull(applicationContext, "createApplicationContext() must not return null.");
57+
58+
HttpHandler httpHandler = WebHttpHandlerBuilder.applicationContext(applicationContext).build();
59+
ServletHttpHandlerAdapter servlet = new ServletHttpHandlerAdapter(httpHandler);
60+
61+
ServletRegistration.Dynamic registration = servletContext.addServlet(servletName, servlet);
62+
Assert.notNull(registration, "Failed to register servlet '" + servletName + "'.");
63+
64+
registration.setLoadOnStartup(1);
65+
registration.addMapping("/");
66+
registration.setAsyncSupported(true);
67+
}
68+
69+
/**
70+
* Return the name to use to register the {@link ServletHttpHandlerAdapter}.
71+
* <p>By default this is {@link #DEFAULT_SERVLET_NAME}.
72+
*/
73+
protected String getServletName() {
74+
return DEFAULT_SERVLET_NAME;
75+
}
76+
77+
/**
78+
* Return the Spring configuration that contains application beans including
79+
* the ones detected by {@link WebHttpHandlerBuilder#applicationContext}.
80+
*/
81+
protected ApplicationContext createApplicationContext() {
82+
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
83+
Class<?>[] configClasses = getConfigClasses();
84+
Assert.notEmpty(configClasses, "No Spring configuration provided.");
85+
return context;
86+
}
87+
88+
/**
89+
* Specify {@link org.springframework.context.annotation.Configuration @Configuration} and/or
90+
* {@link org.springframework.stereotype.Component @Component} classes that
91+
* make up the application configuration. The config classes are given to
92+
* {@linkplain #createApplicationContext()}.
93+
*/
94+
protected abstract Class<?>[] getConfigClasses();
95+
96+
}

spring-webflux/src/main/java/org/springframework/web/reactive/support/AbstractAnnotationConfigDispatcherHandlerInitializer.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,12 @@
2626
* to register a {@code DispatcherHandler}, wrapping it in a
2727
* {@link ServletHttpHandlerAdapter}, and use Java-based Spring configuration.
2828
*
29-
* <p>Concrete implementations are required to implement {@link #getConfigClasses()}.
30-
* Further template and customization methods are provided by
31-
* {@link AbstractDispatcherHandlerInitializer}.
32-
*
3329
* @author Arjen Poutsma
34-
* @since 5.0
30+
* @deprecated in favor of
31+
* {@link org.springframework.web.server.adapter.AbstractReactiveWebInitializer
32+
* AbstractReactiveWebInitializer}
3533
*/
34+
@Deprecated
3635
public abstract class AbstractAnnotationConfigDispatcherHandlerInitializer
3736
extends AbstractDispatcherHandlerInitializer {
3837

spring-webflux/src/main/java/org/springframework/web/reactive/support/AbstractDispatcherHandlerInitializer.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,13 @@
3737
* implementations that register a {@link DispatcherHandler} in the servlet
3838
* context, wrapping it in a {@link ServletHttpHandlerAdapter}.
3939
*
40-
* <p>Most applications should consider extending the Spring Java config, sub-class
41-
* {@link AbstractAnnotationConfigDispatcherHandlerInitializer}.
42-
*
4340
* @author Arjen Poutsma
4441
* @since 5.0
45-
* @see AbstractServletHttpHandlerAdapterInitializer
42+
* @deprecated in favor of
43+
* {@link org.springframework.web.server.adapter.AbstractReactiveWebInitializer
44+
* AbstractReactiveWebInitializer}
4645
*/
46+
@Deprecated
4747
public abstract class AbstractDispatcherHandlerInitializer implements WebApplicationInitializer {
4848

4949
/**

spring-webflux/src/main/java/org/springframework/web/reactive/support/AbstractServletHttpHandlerAdapterInitializer.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,13 @@
3030
* implementations that register a {@link ServletHttpHandlerAdapter} in the
3131
* servlet context.
3232
*
33-
* <p>See {@link AbstractDispatcherHandlerInitializer} if registering a
34-
* {@link org.springframework.web.reactive.DispatcherHandler DispatcherHandler}.
35-
*
3633
* @author Arjen Poutsma
3734
* @since 5.0
38-
* @see AbstractDispatcherHandlerInitializer
35+
* @deprecated in favor of
36+
* {@link org.springframework.web.server.adapter.AbstractReactiveWebInitializer
37+
* AbstractReactiveWebInitializer}
3938
*/
39+
@Deprecated
4040
public abstract class AbstractServletHttpHandlerAdapterInitializer implements WebApplicationInitializer {
4141

4242
/**

src/docs/asciidoc/web/webflux.adoc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -361,9 +361,9 @@ server.start();
361361
[NOTE]
362362
====
363363
To deploy as a WAR to a Servlet 3.1+ container, wrap `HttpHandler` with
364-
`ServletHttpHandlerAdapter` and register that as a `Servlet`. Use
365-
{api-spring-framework}/web/reactive/support/AbstractServletHttpHandlerAdapterInitializer.html[AbstractServletHttpHandlerAdapterInitializer]
366-
to automate the required Servlet container configuration.
364+
`ServletHttpHandlerAdapter` and register that as a `Servlet`.
365+
This can be automated through the use of
366+
{api-spring-framework}/web/server/adapter/AbstractReactiveWebInitializer.html[AbstractReactiveWebInitializer].
367367
====
368368

369369

0 commit comments

Comments
 (0)