springboot默认加载的是tomcat容器,它还有另外两个可选择的容器:jetty和undertow,还有一个Configurable是可以自定义的一个接口;本文不讨论tomcat,jetty,undertow的优劣。感兴趣的同学可以自己查询。
通过org.springframework.boot.web.servlet.server.ServletWebServerFactory的实现就可以知道;那怎么样将默认的tomcat换成jetty或者undertow呢?
其实很简单,以jetty为例,只需要引入org.springframework.boot:spring-boot-starter-jetty包并且排除spring-boot-starter-tomcat包即可;若是要使用undertow,则引用包org.springframework.boot:spring-boot-starter-undertow
gradle配置如下:
configurations {
compile.exclude module: "spring-boot-starter-logging"
compile.exclude module: "spring-boot-starter-tomcat"
}
dependencies {
compile("com.alibaba:fastjson:1.2.75")
compile("mysql:mysql-connector-java")
//spring
compile("org.springframework.boot:spring-boot-starter-jetty")
compile("org.springframework.boot:spring-boot-starter")
compile("org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.4")
compile("org.springframework.boot:spring-boot-starter-web")
compile("org.springframework.boot:spring-boot-starter-actuator")
//compile("org.springframework.boot:spring-boot-starter-aop")
//compile("org.springframework.boot:spring-boot-starter-log4j2")
//lombok
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
//log
compile "org.apache.logging.log4j:log4j-api:2.14.0"
compile "org.apache.logging.log4j:log4j-core:2.14.0"
//test
testCompile('org.springframework.boot:spring-boot-starter-test')
testImplementation 'io.projectreactor:reactor-test'
}
那么我们从源码阶段分析一下,为什么这样配置即可换容器;在包spring-boot-2.4.3.jar中,路径:org.springframework.boot.web.embedded下,有4个包:jetty,netty,tomcat,undertow;统一接口为ServletWebServerFactory,它有三个常用的实现JettyServletWebServerFactory,UndertowServletWebServerFactory,TomcatServletWebServerFactory; 默认会使TomcatServletWebServerFactory该实现; servlet包的context包下ServletWebServerApplicationContext该类createWebServer方法会创建webServer,选择factory的源代码如下:
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);
}
从上面代码就可以看出,排除tomcat包并增加需要使用的容器的包即可
总结:springboot换容器,只需要引入相关包,并且排除默认的tomcat包即可