SpringBoot切换Jetty服务器

结论

只需要修改一下pom.xml,去掉tomcat的依赖,加上jetty的依赖即可。

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
        </dependency>
    </dependencies>

启动日志如下:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.2.5.RELEASE)

2020-03-20 14:07:42.391  INFO 6904 --- [           main] com.example.demo.DemoApplication         : Starting DemoApplication on DESKTOP-GCV0BI2 with PID 6904 (C:\Users\Shadow\IdeaProjects\demo\target\classes started by Shadow in C:\Users\Shadow\IdeaProjects\demo)
2020-03-20 14:07:42.393  INFO 6904 --- [           main] com.example.demo.DemoApplication         : No active profile set, falling back to default profiles: default
2020-03-20 14:07:42.987  INFO 6904 --- [           main] org.eclipse.jetty.util.log               : Logging initialized @1500ms to org.eclipse.jetty.util.log.Slf4jLog
2020-03-20 14:07:43.053  INFO 6904 --- [           main] o.s.b.w.e.j.JettyServletWebServerFactory : Server initialized with port: 8080
2020-03-20 14:07:43.057  INFO 6904 --- [           main] org.eclipse.jetty.server.Server          : jetty-9.4.26.v20200117; built: 2020-01-17T12:35:33.676Z; git: 7b38981d25d14afb4a12ff1f2596756144edf695; jvm 1.8.0_212-b10
2020-03-20 14:07:43.079  INFO 6904 --- [           main] o.e.j.s.h.ContextHandler.application     : Initializing Spring embedded WebApplicationContext
2020-03-20 14:07:43.079  INFO 6904 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 631 ms
2020-03-20 14:07:43.155  INFO 6904 --- [           main] org.eclipse.jetty.server.session         : DefaultSessionIdManager workerName=node0
2020-03-20 14:07:43.155  INFO 6904 --- [           main] org.eclipse.jetty.server.session         : No SessionScavenger set, using defaults
2020-03-20 14:07:43.156  INFO 6904 --- [           main] org.eclipse.jetty.server.session         : node0 Scavenging every 600000ms
2020-03-20 14:07:43.161  INFO 6904 --- [           main] o.e.jetty.server.handler.ContextHandler  : Started o.s.b.w.e.j.JettyEmbeddedWebAppContext@8e76f1{application,/,[file:///C:/Users/Shadow/AppData/Local/Temp/jetty-docbase.1728500713783162746.8080/],AVAILABLE}
2020-03-20 14:07:43.162  INFO 6904 --- [           main] org.eclipse.jetty.server.Server          : Started @1674ms
2020-03-20 14:07:43.263  INFO 6904 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2020-03-20 14:07:43.377  INFO 6904 --- [           main] o.e.j.s.h.ContextHandler.application     : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-03-20 14:07:43.377  INFO 6904 --- [           main] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2020-03-20 14:07:43.381  INFO 6904 --- [           main] o.s.web.servlet.DispatcherServlet        : Completed initialization in 4 ms
2020-03-20 14:07:43.400  INFO 6904 --- [           main] o.e.jetty.server.AbstractConnector       : Started ServerConnector@1080f3a{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
2020-03-20 14:07:43.404  INFO 6904 --- [           main] o.s.b.web.embedded.jetty.JettyWebServer  : Jetty started on port(s) 8080 (http/1.1) with context path '/'
2020-03-20 14:07:43.406  INFO 6904 --- [           main] com.example.demo.DemoApplication         : Started DemoApplication in 1.311 seconds (JVM running for 1.92)

分析过程

  • 从main方法一路断点跟过来,进入创建服务器的方法
	private void createWebServer() {
		WebServer webServer = this.webServer;
		ServletContext servletContext = getServletContext();
		if (webServer == null && servletContext == null) {
			//创建获取一个服务器创建工厂
			ServletWebServerFactory factory = getWebServerFactory();
			//创建服务器
			this.webServer = factory.getWebServer(getSelfInitializer());
		}
		else if (servletContext != null) {
			try {
				getSelfInitializer().onStartup(servletContext);
			}
			catch (ServletException ex) {
				throw new ApplicationContextException("Cannot initialize servlet context", ex);
			}
		}
		initPropertySources();
	}

此时栈信息为:

createWebServer:179, ServletWebServerApplicationContext (org.springframework.boot.web.servlet.context)
onRefresh:153, ServletWebServerApplicationContext (org.springframework.boot.web.servlet.context)
refresh:544, AbstractApplicationContext (org.springframework.context.support)
refresh:141, ServletWebServerApplicationContext (org.springframework.boot.web.servlet.context)
refresh:747, SpringApplication (org.springframework.boot)
refreshContext:397, SpringApplication (org.springframework.boot)
run:315, SpringApplication (org.springframework.boot)
run:1226, SpringApplication (org.springframework.boot)
run:1215, SpringApplication (org.springframework.boot)
main:12, DemoApplication (com.example.demo)
  • 查看方法 getWebServerFactory,发现是在Spring容器中存在一个类型为ServletWebServerFactory的Bean,必须有且只有唯一一个。
	protected ServletWebServerFactory getWebServerFactory() {
		// Use bean names so that we don't consider the hierarchy
		String[] beanNames = getBeanFactory().getBeanNamesForType(ServletWebServerFactory.class);
		if (beanNames.length == 0) {
			throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to missing "
					+ "ServletWebServerFactory bean.");
		}
		if (beanNames.length > 1) {
			throw new ApplicationContextException("Unable to start ServletWebServerApplicationContext due to multiple "
					+ "ServletWebServerFactory beans : " + StringUtils.arrayToCommaDelimitedString(beanNames));
		}
		return getBeanFactory().getBean(beanNames[0], ServletWebServerFactory.class);
	}
  • 通过IDEA的查找Bean的功能,可以很轻易的找到类 ServletWebServerFactoryConfiguration,
    这个类里面有三个内部类,EmbeddedTomcat,EmbeddedJetty,EmbeddedUndertow。并且只有EmbeddedTomcat的 ConditionalOnClass注解没有标红。所以默认使用的是tomcat服务器。
    在这里插入图片描述
  • 现在我要想办法让EmbeddedTomcat的ConditionalOnClass标红,让EmbeddedJetty不红。使用IDEA插件maven-helper里面找tomcat的依赖。明显所有的tomcat依赖是spring-boot-starter-tomcat引入的,所以我要在spring-boot-starter-web 中去除spring-boot-starter-tomcat。
    在这里插入图片描述
    一键去除依赖。
    在这里插入图片描述
  • 引入Jetty的依赖
    盲猜依赖名字为:
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
        </dependency>
  • 此时查看配置类:ServletWebServerFactoryConfiguration,发现EmbeddedTomcat红了,EmbeddedJetty亮了。

在这里插入图片描述

  • 搞完收工
发布了4 篇原创文章 · 获赞 0 · 访问量 75

猜你喜欢

转载自blog.csdn.net/weixin_45957652/article/details/104989048
今日推荐