外部Tomcat容器启动spring-flux
springboot启动类
- 首先继承AbstractReactiveWebInitializer类重写createApplicationContext和getConfigClasses方法
- 配置NettyReactiveWebServerFactory bean(
这个是关键
)
public class DemoBootstrapApplication extends AbstractReactiveWebInitializer {
public static void main(String[] args) {
SpringApplication.run(DemoBootstrapApplication.class, args);
}
@Override
protected ApplicationContext createApplicationContext() {
SpringApplication springApplication = new SpringApplication(getConfigClasses());
return springApplication.run();
}
@Override
protected Class<?>[] getConfigClasses() {
return new Class[]{DemoBootstrapApplication.class};
}
//这里是关键后面再提
@Bean
public NettyReactiveWebServerFactory nettyReactiveWebServerFactory() {
return new NettyReactiveWebServerFactory();
}
}
外置tomcat启动
tomcat 8启动报错如下:
Caused by: org.springframework.context.ApplicationContextException: Unable to start reactive web server; nested exception is java.lang.NoSuchMethodError: org.apache.tomcat.util.modeler.Registry.disableRegistry()V
at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.onRefresh(ReactiveWebServerApplicationContext.java:82)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:577)
at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.refresh(ReactiveWebServerApplicationContext.java:64)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:745)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:420)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:307)
at com.weibo.FizzBootstrapApplication.createApplicationContext(FizzBootstrapApplication.java:198)
at org.springframework.web.server.adapter.AbstractReactiveWebInitializer.onStartup(AbstractReactiveWebInitializer.java:59)
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:174)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4889)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:171)
... 10 more
Caused by: java.lang.NoSuchMethodError: org.apache.tomcat.util.modeler.Registry.disableRegistry()V
at org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFactory.getWebServer(TomcatReactiveWebServerFactory.java:119)
at org.springframework.boot.web.reactive.context.WebServerManager.<init>(WebServerManager.java:50)
at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.createWebServer(ReactiveWebServerApplicationContext.java:94)
at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.onRefresh(ReactiveWebServerApplicationContext.java:79)
... 20 more
- 主要原因是springboot2.x启动时会调用org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFactory类的getWebServer()方法,方法如下,是由于外置tomcat8加载是tomcat-coyote.jar中的Registry类(CATALINA_HOME/lib目录下的jar包),而springboot2.x依赖的是tomcat-embed–core jar(version:9.X,可以理解为tomcat9)造成jar冲突,这里可以尝试采用外置tomcat9.x启动,是不是可以解决jar冲突?,接下来尝试采用tomcat9.0启动
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>9.0.68</version>
</dependency>
@Override
public WebServer getWebServer(HttpHandler httpHandler) {
if (this.disableMBeanRegistry) {
//这里报错,找不到disableRegistry方法
Registry.disableRegistry();
}
Tomcat tomcat = new Tomcat();
File baseDir = (this.baseDirectory != null) ? this.baseDirectory : createTempDir("tomcat");
tomcat.setBaseDir(baseDir.getAbsolutePath());
for (LifecycleListener listener : this.serverLifecycleListeners) {
tomcat.getServer().addLifecycleListener(listener);
}
Connector connector = new Connector(this.protocol);
connector.setThrowOnFailure(true);
tomcat.getService().addConnector(connector);
customizeConnector(connector);
tomcat.setConnector(connector);
tomcat.getHost().setAutoDeploy(false);
configureEngine(tomcat.getEngine());
for (Connector additionalConnector : this.additionalTomcatConnectors) {
tomcat.getService().addConnector(additionalConnector);
}
TomcatHttpHandlerAdapter servlet = new TomcatHttpHandlerAdapter(httpHandler);
prepareContext(tomcat.getHost(), servlet);
return getTomcatWebServer(tomcat);
}
tomcat 9启动:
Caused by: java.lang.ClassNotFoundException: org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at org.apache.catalina.loader.WebappLoader.createClassLoader(WebappLoader.java:515)
at org.apache.catalina.loader.WebappLoader.startInternal(WebappLoader.java:389)
... 79 more
- 问题原因
- 解决
@Configuration
@ConditionalOnMissingBean(ReactiveWebServerFactory.class)
@ConditionalOnClass({ HttpServer.class })
static class EmbeddedNetty {
@Bean
public NettyReactiveWebServerFactory nettyReactiveWebServerFactory() {
return new NettyReactiveWebServerFactory();
}
}
@Configuration
@ConditionalOnMissingBean(ReactiveWebServerFactory.class)
@ConditionalOnClass({ org.apache.catalina.startup.Tomcat.class })
static class EmbeddedTomcat {
@Bean
public TomcatReactiveWebServerFactory tomcatReactiveWebServerFactory() {
return new TomcatReactiveWebServerFactory();
}
}
tomcat9启动失败主要原因
- 内嵌(embed)的tomcat的类加载器是 TomcatEmbeddedWebappClassLoader, 需要用此类加载器加载web应用的类, 而这个类加载器首先需要被 tomcat 的 WebappClassLoader 加载, 但是WebappClassLoader加载的是CATALINA_HOME/lib目录下的类, 因此 TomcatEmbeddedWebappClassLoader 无法加载, 在加载WEB-INF下的类之前就会抛出ClassNotFound异常。
注入NettyReactiveWebServerFactory造成的问题
原文地址:https://blog.csdn.net/shb1224/article/details/134581778
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_28426.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。