@ -16,10 +16,13 @@
@@ -16,10 +16,13 @@
package org.springframework.web.server.adapter ;
import javax.servlet.ServletContext ;
import javax.servlet.ServletContextEvent ;
import javax.servlet.ServletContextListener ;
import javax.servlet.ServletException ;
import javax.servlet.ServletRegistration ;
import org.springframework.context.ApplicationContext ;
import org.springframework.context.ConfigurableApplicationContext ;
import org.springframework.context.annotation.AnnotationConfigApplicationContext ;
import org.springframework.http.server.reactive.HttpHandler ;
import org.springframework.http.server.reactive.ServletHttpHandlerAdapter ;
@ -55,6 +58,9 @@ public abstract class AbstractReactiveWebInitializer implements WebApplicationIn
@@ -55,6 +58,9 @@ public abstract class AbstractReactiveWebInitializer implements WebApplicationIn
ApplicationContext applicationContext = createApplicationContext ( ) ;
Assert . notNull ( applicationContext , "createApplicationContext() must not return null." ) ;
refreshApplicationContext ( applicationContext ) ;
registerCloseListener ( servletContext , applicationContext ) ;
HttpHandler httpHandler = WebHttpHandlerBuilder . applicationContext ( applicationContext ) . build ( ) ;
ServletHttpHandlerAdapter servlet = new ServletHttpHandlerAdapter ( httpHandler ) ;
@ -82,17 +88,45 @@ public abstract class AbstractReactiveWebInitializer implements WebApplicationIn
@@ -82,17 +88,45 @@ public abstract class AbstractReactiveWebInitializer implements WebApplicationIn
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext ( ) ;
Class < ? > [ ] configClasses = getConfigClasses ( ) ;
Assert . notEmpty ( configClasses , "No Spring configuration provided." ) ;
context . register ( configClasses ) ;
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 ( ) } .
* 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 ( ) ;
/ * *
* Refresh the given application context , if necessary .
* /
protected void refreshApplicationContext ( ApplicationContext context ) {
if ( context instanceof ConfigurableApplicationContext ) {
ConfigurableApplicationContext cac = ( ConfigurableApplicationContext ) context ;
if ( ! cac . isActive ( ) ) {
cac . refresh ( ) ;
}
}
}
/ * *
* Register a { @link ServletContextListener } that closes the given
* application context when the servlet context is destroyed .
* @param servletContext the servlet context to listen to
* @param applicationContext the application context that is to be
* closed when { @code servletContext } is destroyed
* /
protected void registerCloseListener ( ServletContext servletContext , ApplicationContext applicationContext ) {
if ( applicationContext instanceof ConfigurableApplicationContext ) {
ConfigurableApplicationContext cac = ( ConfigurableApplicationContext ) applicationContext ;
ServletContextDestroyedListener listener = new ServletContextDestroyedListener ( cac ) ;
servletContext . addListener ( listener ) ;
}
}
/ * *
* Return the Servlet mapping to use . Only the default Servlet mapping '/'
* and path - based Servlet mappings such as ' / api / * ' are supported .
@ -102,4 +136,23 @@ public abstract class AbstractReactiveWebInitializer implements WebApplicationIn
@@ -102,4 +136,23 @@ public abstract class AbstractReactiveWebInitializer implements WebApplicationIn
return "/" ;
}
private static class ServletContextDestroyedListener implements ServletContextListener {
private final ConfigurableApplicationContext applicationContext ;
public ServletContextDestroyedListener ( ConfigurableApplicationContext applicationContext ) {
this . applicationContext = applicationContext ;
}
@Override
public void contextInitialized ( ServletContextEvent sce ) {
}
@Override
public void contextDestroyed ( ServletContextEvent sce ) {
this . applicationContext . close ( ) ;
}
}
}