作为WAR运行Spring Webflux应用程序

问题描述:

我有一个弹簧反应sample application,它是从Spring Webflux documentation中提供的示例之一修改而来的。该应用程序的master分支以传统方式使用Spring Boot,并使用嵌入式应用程序服务器(Netty)。它工作正常。作为WAR运行Spring Webflux应用程序

Liberty branch中,我试图将应用程序构建为WAR并部署到Websphere Liberty Profile。除了更改构建过程中,最显著代码的变化,就是我Application.java(来源here)延长AbstractAnnotationConfigDispatcherHandlerInitializer,按Webflux文件:

对于Servlet容器尤其是WAR部署中,可以使用AbstractAnnotationConfigDispatcherHandlerInitializer其作为WebApplicationInitializer并由Servlet容器自动检测。它负责注册ServletHttpHandlerAdapter,如上所示。你将需要实现一个抽象方法来指向你的Spring配置。

但是,当我这样做时,我的资源/端点都没有被映射,并且我在Application.java中声明的我的bean都没有被注册。这是一个完整的输出,我得到的,不同之处时,试图访问上下文根被抛出:

13:29:48.848 [Default Executor-thread-6] DEBUG org.springframework.context.annotation.ClassPathBeanDefinitionScanner - JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning 
13:29:48.855 [Default Executor-thread-6] INFO org.springframework.context.annotation.AnnotationConfigApplicationContext - Refreshing org.spring[email protected]4ba0f9a4: startup date [Fri Oct 13 13:29:48 CDT 2017]; root of context hierarchy 
13:29:48.857 [Default Executor-thread-6] DEBUG org.springframework.context.annotation.AnnotationConfigApplicationContext - Bean factory for org.spring[email protected]4ba0f9a4: org.s[email protected]41daf3ea: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory]; root of factory hierarchy 
13:29:48.907 [Default Executor-thread-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor' 
13:29:48.907 [Default Executor-thread-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating instance of bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor' 
13:29:48.939 [Default Executor-thread-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Eagerly caching bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor' to allow for resolving potential circular references 
13:29:48.943 [Default Executor-thread-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Finished creating instance of bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor' 
13:29:49.371 [Default Executor-thread-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor' 
13:29:49.371 [Default Executor-thread-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating instance of bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor' 
13:29:49.372 [Default Executor-thread-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Eagerly caching bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor' to allow for resolving potential circular references 
13:29:49.425 [Default Executor-thread-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Finished creating instance of bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor' 
13:29:49.426 [Default Executor-thread-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalRequiredAnnotationProcessor' 
13:29:49.426 [Default Executor-thread-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating instance of bean 'org.springframework.context.annotation.internalRequiredAnnotationProcessor' 
13:29:49.428 [Default Executor-thread-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Eagerly caching bean 'org.springframework.context.annotation.internalRequiredAnnotationProcessor' to allow for resolving potential circular references 
13:29:49.432 [Default Executor-thread-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Finished creating instance of bean 'org.springframework.context.annotation.internalRequiredAnnotationProcessor' 
13:29:49.433 [Default Executor-thread-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor' 
13:29:49.433 [Default Executor-thread-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating instance of bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor' 
13:29:49.441 [Default Executor-thread-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Eagerly caching bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor' to allow for resolving potential circular references 
13:29:49.450 [Default Executor-thread-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Finished creating instance of bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor' 
13:29:49.454 [Default Executor-thread-6] DEBUG org.springframework.context.annotation.AnnotationConfigApplicationContext - Unable to locate MessageSource with name 'messageSource': using default [[email protected]ddc5] 
13:29:49.458 [Default Executor-thread-6] DEBUG org.springframework.context.annotation.AnnotationConfigApplicationContext - Unable to locate ApplicationEventMulticaster with name 'applicationEventMulticaster': using default [org.[email protected]6a00d295] 
13:29:49.461 [Default Executor-thread-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Pre-instantiating singletons in org.s[email protected]41daf3ea: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory]; root of factory hierarchy 
13:29:49.462 [Default Executor-thread-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor' 
13:29:49.462 [Default Executor-thread-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor' 
13:29:49.462 [Default Executor-thread-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.context.annotation.internalRequiredAnnotationProcessor' 
13:29:49.463 [Default Executor-thread-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor' 
13:29:49.463 [Default Executor-thread-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerProcessor' 
13:29:49.463 [Default Executor-thread-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating instance of bean 'org.springframework.context.event.internalEventListenerProcessor' 
13:29:49.477 [Default Executor-thread-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Eagerly caching bean 'org.springframework.context.event.internalEventListenerProcessor' to allow for resolving potential circular references 
13:29:49.479 [Default Executor-thread-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Finished creating instance of bean 'org.springframework.context.event.internalEventListenerProcessor' 
13:29:49.480 [Default Executor-thread-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerFactory' 
13:29:49.480 [Default Executor-thread-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating instance of bean 'org.springframework.context.event.internalEventListenerFactory' 
13:29:49.481 [Default Executor-thread-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Eagerly caching bean 'org.springframework.context.event.internalEventListenerFactory' to allow for resolving potential circular references 
13:29:49.483 [Default Executor-thread-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Finished creating instance of bean 'org.springframework.context.event.internalEventListenerFactory' 
13:29:49.484 [Default Executor-thread-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.context.event.internalEventListenerFactory' 
13:29:49.514 [Default Executor-thread-6] DEBUG org.springframework.context.annotation.AnnotationConfigApplicationContext - Unable to locate LifecycleProcessor with name 'lifecycleProcessor': using default [[email protected]fc157d] 
13:29:49.515 [Default Executor-thread-6] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'lifecycleProcessor' 
13:29:49.520 [Default Executor-thread-6] DEBUG org.springframework.core.env.PropertySourcesPropertyResolver - Could not find key 'spring.liveBeansView.mbeanDomain' in any property source 
[AUDIT ] CWWKZ0001I: Application spring-reactive-playground started in 3.480 seconds. 
[AUDIT ] CWWKF0012I: The server installed the following features: [servlet-3.1, websocket-1.1]. 
[AUDIT ] CWWKF0011I: The server LibertyProjectServer is ready to run a smarter planet. 
13:30:05.943 [Default Executor-thread-14] DEBUG reactor.util.Loggers$LoggerFactory - Using Slf4j logging framework 
13:30:05.994 [Default Executor-thread-14] DEBUG org.springframework.web.reactive.DispatcherHandler - Processing GET request for [http://localhost:9080/] 
13:30:06.041 [Default Executor-thread-14] ERROR org.springframework.web.server.adapter.HttpWebHandlerAdapter - Failed to handle request 
org.springframework.web.server.ResponseStatusException: Response status 404 with reason "No matching handler" 
     at org.springframework.web.reactive.DispatcherHandler.<clinit>(DispatcherHandler.java:74) 
     at org.springframework.web.reactive.support.AbstractDispatcherHandlerInitializer.createDispatcherHandler(AbstractDispatcherHandlerInitializer.java:145) 
     at org.springframework.web.reactive.support.AbstractDispatcherHandlerInitializer.registerDispatcherHandler(AbstractDispatcherHandlerInitializer.java:90) 
     at org.springframework.web.reactive.support.AbstractDispatcherHandlerInitializer.onStartup(AbstractDispatcherHandlerInitializer.java:63) 
     at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:172) 
     at com.ibm.ws.webcontainer.webapp.WebApp.initializeServletContainerInitializers(WebApp.java:2539) 
     at com.ibm.ws.webcontainer.webapp.WebApp.initialize(WebApp.java:1055) 
     at com.ibm.ws.webcontainer.webapp.WebApp.initialize(WebApp.java:6595) 
     at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost.startWebApp(DynamicVirtualHost.java:468) 
     at com.ibm.ws.webcontainer.osgi.DynamicVirtualHost.startWebApplication(DynamicVirtualHost.java:463) 
     at com.ibm.ws.webcontainer.osgi.WebContainer.startWebApplication(WebContainer.java:1120) 
     at com.ibm.ws.webcontainer.osgi.WebContainer.startModule(WebContainer.java:925) 
     at com.ibm.ws.app.manager.module.internal.ModuleHandlerBase.deployModule(ModuleHandlerBase.java:100) 
     at com.ibm.ws.app.manager.module.internal.DeployedModuleInfoImpl.installModule(DeployedModuleInfoImpl.java:50) 
     at com.ibm.ws.app.manager.module.internal.DeployedAppInfoBase.deployModules(DeployedAppInfoBase.java:420) 
     at com.ibm.ws.app.manager.module.internal.DeployedAppInfoBase.deployApp(DeployedAppInfoBase.java:406) 
     at com.ibm.ws.app.manager.war.internal.WARApplicationHandlerImpl.install(WARApplicationHandlerImpl.java:66) 
     at com.ibm.ws.app.manager.internal.statemachine.StartAction.execute(StartAction.java:141) 
     at com.ibm.ws.app.manager.internal.statemachine.ApplicationStateMachineImpl.enterState(ApplicationStateMachineImpl.java:1259) 
     at com.ibm.ws.app.manager.internal.statemachine.ApplicationStateMachineImpl.run(ApplicationStateMachineImpl.java:874) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
     at java.lang.Thread.run(Thread.java:748) 

我也曾尝试部署到Tomcat 9,我也得到了同样的问题。我之前通过扩展SpringBootServletInitializer而不是AbstractAnnotationConfigDispatcherHandlerInitializer成功地将传统的Spring MVC应用程序部署为WAR。 Spring Webflux应用程序的等效过程是什么?我在项目代码中缺少什么?

+0

你能否在jira.spring.io上创建一个关于repro项目的问题,团队可以看一看? –

+0

嗨@BrianClozel,是的,我在这里提交了问题:https://jira.spring.io/browse/SPR-16084 – Charles

Spring 5为基于webflux的应用程序带来了WebApplicationInitializer的一些变体。

春5.0.2之前(春季启动2.0.0.M7与此版本一致),存在AbstractAnnotationConfigDispatcherHandlerInitializer一个bug,并在5.0.2,这个类被标记为@Deprecated,有推出了新的AbstractReactiveWebInitializer。但这个班似乎也是越野车,我不得不重写createApplicationContext()以使其工作。 查看我的示例AppInitializer中的注释以了解更多详情。

检查my workable war sample在tomcat上测试成功。