场景
在我们将SpringBoot项目部署到Tomcat是,会一直报端口被占用的错误,Tomcat无法启动。我们既想在开发中使用内嵌Tomcat自动启动,又想在部署时排除内嵌Tomcat.
原因
产生该问题的原因是因为SpringBoot项目本身内嵌了Tomcat,当我们启动项目是,其内部的Tomcat也启动了,因此造成端口被占用的问题。
解决方案
- 去除SpingBoot框架内嵌的Tomcat服务器,其Tomcat是集成在spring-boot-starter-web中的,如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<!-- 参与项目编译运行,但是不参与项目打包,打包时相当于在spring-boot-starter-web中exclude-->
<scope>provided</scope>
</dependency>
<!--添加servlet-api依赖:SpringBootServletInitializer接口需要该包-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<!-- 参与项目编译运行,但是不参与项目打包-->
<scope>provided</scope>
</dependency>
等价于
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- Maven整个生命周期内排除内置容器,排除内置容器导出成war包可以让外部容器运行spring-boot项目-->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
- SpringBoot主程序继承SpringBootServletInitializer并重写configure方法
@SpringBootApplication
public class SpringBootMainApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(SpringBootMainApplication.class, args);
}
// 重写configure,设置启动类被本类。
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(SpringBootMainApplication.class);
}
}
- 如果在IDEA中,Run–>Edit Configuration…
确认选中红色选项为选中状态