作为一名从Spring Boot 1.x时代就开始使用的老鸟,我见过太多新手在入门时被这三个问题折磨得死去活来。今天我就用最接地气的方式,带你们彻底搞懂这些坑。
先看个真实案例:上周团队新来的实习生小张,在本地调试时遇到了端口占用问题。他先是疯狂点击停止按钮,然后重启IDE,最后甚至重启了电脑——典型的"三板斧"操作。结果问题依旧,急得他差点把键盘摔了。其实只要理解Spring Boot的运行机制,这类问题都能迎刃而解。
当你看到这样的错误日志时:
code复制***************************
APPLICATION FAILED TO START
***************************
Description:
Web server failed to start. Port 8080 was already in use.
这表示内嵌Tomcat在启动时尝试绑定8080端口失败了。根本原因是操作系统级别的端口冲突。
在application.properties中:
properties复制server.port=9090
或者在application.yml中:
yaml复制server:
port: 9090
注意:yml文件对缩进敏感,必须使用空格而非Tab
bash复制java -jar your-app.jar --server.port=9090
properties复制server.port=0
启动后日志会显示实际分配的端口号。
java复制@SpringBootApplication
public class MyApp {
public static void main(String[] args) {
new SpringApplicationBuilder(MyApp.class)
.properties("server.port=9090")
.run(args);
}
}
Linux/Mac:
bash复制lsof -i :8080
kill -9 <PID>
Windows:
cmd复制netstat -ano | findstr 8080
taskkill /F /PID <PID>
运行以下命令查看完整依赖树:
bash复制mvn dependency:tree
示例输出片段:
code复制[INFO] com.example:demo:jar:0.0.1-SNAPSHOT
[INFO] +- org.springframework.boot:spring-boot-starter-web:jar:3.2.0
[INFO] | \- org.apache.tomcat.embed:tomcat-embed-core:jar:10.1.16
[INFO] \- org.apache.commons:commons-lang3:jar:3.8
xml复制<dependency>
<groupId>problematic.group</groupId>
<artifactId>problematic-artifact</artifactId>
<exclusions>
<exclusion>
<groupId>conflict.group</groupId>
<artifactId>conflict-artifact</artifactId>
</exclusion>
</exclusions>
</dependency>
在pom.xml的
xml复制<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.13.0</version>
</dependency>
</dependencies>
</dependencyManagement>
xml复制<properties>
<commons-lang3.version>3.13.0</commons-lang3.version>
</properties>
bash复制mvn dependency:analyze
启动时添加--debug参数:
bash复制java -jar your-app.jar --debug
关键日志解读:
code复制=========================
AUTO-CONFIGURATION REPORT
=========================
Positive matches:
-----------------
DataSourceAutoConfiguration matched:
- @ConditionalOnClass found required classes 'javax.sql.DataSource', 'org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType' (OnClassCondition)
Negative matches:
-----------------
ActiveMQAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'javax.jms.ConnectionFactory' (OnClassCondition)
bash复制curl http://localhost:8080/actuator/env
java复制@Autowired
private Environment env;
public void checkConfig() {
System.out.println(env.getProperty("your.config.key"));
}
java复制@ConfigurationProperties(prefix = "app")
public class AppProperties {
private String name;
// getters & setters
}
bash复制java -jar -Dspring.profiles.active=prod your-app.jar
现象:子模块A需要Guava 28.0,子模块B需要Guava 31.0
解决方案:在父pom的dependencyManagement中统一指定版本
现象:本地运行正常,部署到K8s后配置不生效
原因:配置被ConfigMap覆盖
解决方案:使用kubectl describe pod查看实际注入的环境变量
现象:引入SDK后出现NoClassDefFoundError
排查:使用mvn dependency:tree发现SDK依赖了特定版本的slf4j
解决:添加对应的依赖或排除冲突版本
记住,这些看似麻烦的问题,正是你深入理解Spring Boot的契机。每个解决的过程,都是你技术成长的脚印。