場景
在我們將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…
確認選中紅色選項爲選中狀態