FEATURED · 精选文章

IDEA+SpringBoot环境搭建:JDK、Maven与启动排错

发布时间 / 2026/9/18 3:06:56
来源 / 创域科博编辑部
栏目 / 资讯中心
IDEA+SpringBoot环境搭建:JDK、Maven与启动排错 第一次拿到一台干净的机器装完IDEA想跑一个SpringBoot项目很多人卡住的地方往往不是代码本身而是环境。我自己换机器、换系统、换JDK版本的次数不算少每次重新配一遍IDEA和SpringBoot环境踩的坑基本都集中在几处看着不起眼的地方本机装了两三个JDK导致编译和运行用的不是一个、Maven本地仓库路径里带了中文、Spring Initializr里那个版本下拉框找不到自己能用的选项。这些事单拎出来都不难但凑在一起足够让人对着控制台发一下午呆。下面这套流程从IDEA的版本选择、JDK与Maven的前置确认到用Spring Initializr把项目建出来、写一个能返回JSON的接口、再一路排掉首次启动几乎必然撞上的几个报错我会按我实际操作的顺序讲。刚接触SpringBoot的人照着能走通已经写过一阵子的人里面关于版本匹配和IDEA几处配置的细节应该也能帮你省点时间。1. IDEA与JDK动手建项目之前必须先敲定的两件事很多人一上来就点New Project然后卡在下一步的版本下拉框里。问题不在那一步而在更前面——你机器上到底装了哪个JDK你打算用哪个IDEA版本这两个东西决定了后面能选什么。顺序反了后面全是回头路。1.1 社区版够不够用别在版本选择上纠结太久IDEA分社区版Community和旗舰版Ultimate。旗舰版内置了完整的Spring支持包括Spring Beans依赖关系视图、Spring Boot运行面板、更多的Spring配置文件提示社区版从2020.1之后的版本也开始提供Spring Boot项目创建能力日常写接口、跑项目、调试是完全够的。差别主要体现在辅助功能上比如你想在IDE里直接看到某个Bean是从哪注进来的、有哪些候选社区版就得靠Ctrl鼠标点进去自己翻旗舰版有专门的视图。我的建议很直接学生或者只是自己练手、做个人项目社区版就够别为了几个辅助视图去折腾。工作里如果团队统一买了旗舰版授权那就用旗舰版省下的排查时间值那个钱。这里有个容易被忽略的点——IDEA的版本不要装得太旧。太旧的版本可能不支持较新的JDK语法特性和Spring Boot 3的一些配置文件高亮会出现代码能跑但IDE飘红的尴尬情况。不用追最新选当前年份往前一到两个大版本就行。1.2 JDK版本和SpringBoot版本不是随便配的这是新手栽得最多的地方。SpringBoot 3.x系列要求JDK 17作为最低版本你机器上装的是JDK 8创建项目时选了3.xIDEA会在编译阶段直接报错提示class文件版本不匹配。反过来SpringBoot 2.7.x系列最低支持JDK 8用它跑在JDK 17上一般也能work但个别第三方库会出兼容性问题。我一般这样定你的JDK建议的SpringBoot版本备注JDK 82.7.x2.7.x已停止开源维护新项目不建议再用JDK 112.7.x过渡选择企业老项目常见JDK 173.x当前新项目的主流组合JDK 213.2.x及以上可以用虚拟线程等新特性确认本机JDK的办法很简单开一个终端敲java -version和javac -version注意这两个的输出要一致。经常出现的情况是java指向JDK 17javac却指向JDK 8因为PATH里前面的那个是JRE目录。IDEA里还要再核一次File → Project Structure → Project把Project SDK和Language level都设成同一个JDK。这两处不一致会出现IDEA里编译通过、命令行打包失败或者反过来。1.3 Maven仓库、镜像和IDEA里的绑定关系Maven这件事有三个路径要分清Maven程序自己的安装路径Maven home、配置文件settings.xml的路径、以及本地仓库local repository的路径。默认情况下本地仓库在用户目录下的.m2/repository一旦你的系统用户名是中文这个路径就带中文某些老版本的依赖解析会在这个路径上出问题报错信息还特别隐晦。我习惯在settings.xml里手动指定一个纯英文路径localRepositoryD:/dev/maven-repo/localRepository紧接着是镜像。默认走中央仓库国内拉依赖的速度你懂的。在settings.xml的mirrors节点里加一段国内镜像注意mirrorOf写*会拦截所有仓库请求包括一些公司私服如果你后面要连私服这里要改成central或者用*,!私服id的写法排除掉mirror idaliyun-public/id mirrorOf*/mirrorOf namealiyun public/name urlhttps://maven.aliyun.com/repository/public/url /mirror配完之后IDEA里要明确告诉它用哪个Settings → Build, Execution, Deployment → Build Tools → Maven把Maven home path、User settings file、Local repository三项都手动指过去不要用默认的Bundled版本。IDEA自带的Bundled Maven版本往往偏旧和你在settings.xml里写的配置不一定对得上。这三项一旦统一后面依赖下载慢、依赖找不到的问题能少一大半。2. 创建SpringBoot项目三条路的取舍环境确认完接下来建项目。你可能见过三种做法IDEA里直接点Spring Initializr、去官网下载压缩包再导入、以及手动建Maven项目自己写pom。三条路都能到终点区别在于网络环境和你想不想搞清楚项目到底由什么组成。2.1 IDEA内置的Spring Initializr怎么点New Project → 左侧选Spring Initializr顶部Server URL默认是start.spring.io。这一步如果卡很久说明你的网络访问不到那个地址直接跳到2.2。能访问的话填写这几项ProjectMavenGradle用户选GradleLanguageJavaSpring Boot选一个3.x里带(SNAPSHOT)的别选选正式发布版Group包名前缀一般写公司域名倒过来个人项目写com.example也行Artifact项目名会作为jar包名的一部分PackagingJar除非明确要部署到外置容器否则别选WarJava选17或21跟前面确认的JDK一致下一步Dependencies只勾Spring Web就够了。新手常见的问题是勾了一堆自己根本不用的依赖结果依赖冲突排查起来头大。项目骨架建出来之后pom里会自带parent、spring-boot-starter-web和spring-boot-maven-plugin三块核心内容先跑通再往里加东西。2.2 官网下载压缩包再导入网络不通时的稳妥做法访问不了start.spring.io的情况很常见。这时打开浏览器访问官网的Initializr页面参数填法完全一样点Generate下载一个zip包。解压到一个纯英文、无空格的路径下比如D:/code/demo。然后在IDEA里不选New Project而是选Open直接指向解压后的文件夹。IDEA识别到pom.xml会自动当成Maven项目导入右下角弹窗问你是否作为Maven项目加载点确认接着它会开始下载依赖。这个过程第一次会比较久进度条在底部状态栏别以为它卡死了。提示解压路径不要放在桌面或者我的文档里路径里带中文或空格Maven和Spring Boot偶尔会在解析资源文件时出问题报错还很难往路径上想。2.3 手工搭一个Maven项目把pom写明白如果你想把项目的每个组成搞透可以自己建一个普通Maven项目然后手动补pom。核心就三块parent负责统一版本管理starter-web负责引入Web相关的一整套依赖plugin负责把项目打成可执行的jarparent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version3.2.5/version relativePath/ /parent dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency /dependencies build plugins plugin groupIdorg.springframework.boot/groupId artifactIdspring-boot-maven-plugin/artifactId /plugin /plugins /build注意parent里的version一旦写了下面所有starter的版本都不用写由parent统一管这就是为什么大家推荐用spring-boot-starter-parent的原因。你如果见过别人的pom里每个依赖都写了版本号那多半是没用parent或者被自己的BOM覆盖了。手工搭建的好处是你清楚每个依赖从哪来坏处是容易漏掉packaging、java.version这些属性建议对着Initializr生成的项目比对一下。3. 第一个接口从启动类到浏览器里看到JSON项目骨架有了接下来写点能跑起来的东西。SpringBoot最小可用项目的入口是一个带SpringBootApplication的类内容几乎不用改真正需要理解的是它的目录位置。3.1 目录层级决定了你的类能不能被扫描到SpringBootApplication这个注解内部包含了ComponentScan它默认从注解所在类的包开始向下扫描。也就是说你的启动类放在com.example.demo下那么com.example.demo.controller、com.example.demo.service里的类才能被扫到你要是新建一个com.example.other包把Controller扔进去启动时日志里根本看不到它映射的路径浏览器访问404你还会以为代码写错了。这个坑我见过太多次启动成功但接口404十有八九就是包放外面的。解决办法要么把类挪回启动类的子包要么在启动类上加ComponentScan(com.example)显式指定。新人阶段我建议用第一种保持包结构规范后面拆模块也顺。标准结构大概是com.example.demo.DemoApplication启动类com.example.demo.controller.HelloControllercom.example.demo.service.XxxServicecom.example.demo.entity.Xxx3.2 写一个返回JSON的Controller新建一个Controller类加上RestController写个方法返回Mappackage com.example.demo.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.Map; RestController public class HelloController { GetMapping(/hello) public String hello() { return hello springboot; } GetMapping(/user) public MapString, Object user() { MapString, Object result new HashMap(); result.put(name, tom); result.put(age, 18); return result; } }这里有个细节值得说清楚RestController等于Controller加ResponseBody。你如果只写Controller返回字符串时它会把hello springboot当成一个视图名去找模板文件找不到就报错返回Map时它也没法序列化成JSON。很多人从教程里抄代码时把注解抄成Controller然后死活调不通原因就在这。Map被返回成JSON靠的是SpringBoot自动配置里引入的Jackson。spring-boot-starter-web里已经带了Jackson依赖不用额外加。如果你返回一个自定义的实体类同样会被序列化成JSON字段名默认就是属性名。3.3 启动日志里真正该看的几行点IDEA右上角的绿色三角运行启动类。控制台会打印一段启动日志新手一般只看最后一行Started xxx in x seconds。其实前面几行信息量更大第一行的Banner那是SpringBoot的默认图案不影响运行Tomcat initialized with port(s): 8080端口就在这行看的改端口也是改这里生效Mapped {[/hello],methods[GET]}每注册一个接口都会打印这行你写的接口如果没出现在这里说明它没被扫描到最后Started DemoApplication in 1.234 seconds只代表Spring上下文初始化完成不代表端口已经能访问浏览器打开http://localhost:8080/hello看到字符串就通了打开/user看到{name:tom,age:18}格式的JSON。如果页面是404回头看上一节的包扫描如果是500看控制台有没有异常堆栈一般是某个Bean注入失败。4. 首次启动几乎躲不掉的几个报错能一次跑通当然好实际第一次大概率会撞上下面几个。我按报错信息→真正原因→怎么定位的顺序写照着排查基本能一次定位。4.1 端口被占用日志只给了一句Web server failed to start报错长这样Port 8080 was already in use。8080这个端口太抢手被别的进程占着是常事。找占用进程# Windows netstat -ano | findstr :8080 # macOS / Linux lsof -i:8080Windows下拿到PID后去任务管理器结束或者直接taskkill /PID 进程号 /F。更省事的做法是改自己项目的端口在src/main/resources/application.properties里加一行server.port8081改完重启即可。这里要提醒一句如果你用了devtools改配置不一定自动生效配置文件的变更有时候需要手动重启一次才稳。别反复改端口以为没生效其实是没有重启。4.2 依赖拉了半天最后报Could not resolve这种报错列表能刷满整个控制台核心就一句某个依赖解析不到。原因一般是三个——镜像没配好、本地仓库里下载了半截的损坏文件、或者公司网络需要走私有仓库。先确认镜像命令行运行mvn help:effective-settings能看到最终生效的settings.xml内容确认你配的mirrors在里面。然后清本地仓库里对应的那部分最狠的办法是整个删掉repository目录重下代价大但最有效。更精准的是根据报错里的路径去本地仓库删掉对应文件夹下的.lastUpdated文件再重新导入。有个经验IDEA里的Maven面板有个刷新按钮很多人不点改完settings.xml直接运行项目用的还是旧配置。改完配置一定要点一下刷新让IDEA重新加载。4.3 版本不兼容报unsupported class file major version这个报错意思是编译出来的class用了比你运行环境更高的版本。JDK 17编译的class是major version 61你用JDK 8的JRE去跑就会报。看到major version 61基本就是JDK版本低了major version 65就是JDK 21。排查顺序是命令行java -version看运行时的JDKmvn -version看Maven用的JDKIDEA Project Structure里看Project SDKpom里java.version看编译目标。四处对齐了这个错就没了。最常见的是机器上装了两个JDKIDEA用了新的环境变量指向旧的命令行打包跑出来就报这个错。4.4 改了代码要重启才生效写业务的时候每次改一行代码就手动停掉重跑效率极低。SpringBoot提供了devtools来解决这个。但注意devtools不是真的热替换它是检测到class文件变化后重启应用上下文速度比冷启动快但不是零延迟。配置方式是在pom里加依赖dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-devtools/artifactId scoperuntime/scope optionaltrue/optional /dependency加了依赖还不够IDEA里要打开两处开关Settings → Build, Execution, Deployment → Compiler勾上Build project automatically再用快捷键调出Registry较新版本用Find Action搜Registry勾上compiler.automake.allow.when.app.running。这两处不打开devtools形同虚设你会以为是它坏了。5. 让它顺手一点的几个日常配置跑通第一个接口之后接下来是让后续开发舒服。下面这几个配置不算必须但几乎每个项目都会用到。5.1 多环境配置文件怎么拆开发、测试、生产用的数据库地址、端口、日志级别都不一样把这些全塞在application.properties里改来改去容易出错。主流的做法是按profile拆文件application.yml放公共配置指定激活的环境application-dev.yml开发环境application-test.yml测试环境application-prod.yml生产环境主文件里写spring: profiles: active: dev启动时会自动加载application-dev.yml里的配置同名配置后者覆盖前者。打包上线时不想改代码可以在启动命令里指定java -jar demo-0.0.1-SNAPSHOT.jar --spring.profiles.activeprod这里有个顺序要记住命令行参数 环境变量 外部配置文件 内部配置文件。搞不清覆盖顺序时用这个规则往上套基本都能推出来最终生效的是哪个值。5.2 IDEA运行配置里的几个开关IDEA每个项目有一套Run/Debug Configuration点运行按钮旁边那个下拉Edit Configurations进去。这里有几处值得改Active profiles一栏在多环境项目里可以指定当前跑哪个profile和配置文件里的active作用一样但优先级更高方便本地切换VM options里可以加-Dfile.encodingUTF-8避免控制台中文乱码勾上Allow multiple instances在你需要同时跑两个端口的时候有用另外Maven面板也值得熟悉一下Lifecycle里的clean、package、install几个命令双击就能跑比敲命令快。跑package的时候注意先clean否则上一次的产物可能混进去。5.3 一个关于Banner的小补充启动时打印的那个SpringBoot图案是可以换掉的在src/main/resources下放一个banner.txt重启后就会打印你自定义的内容。功能上完全没用但能在日志里快速认出是哪个项目在跑团队里几个服务同时在的时候还挺实用。自定义Banner的生成现在有很多在线工具输入文字导出文本粘进去就行。注意banner.txt编码要和IDEA的文件编码设置一致不然会显示乱码。6. 打一个可执行jar在本地完整走一遍部署开发环境跑通不代表能部署。最后这一步是把项目打成jar包脱离IDEA用命令行启动一次。6.1 spring-boot-maven-plugin到底做了什么mvn clean package执行时构建过程会调用spring-boot-maven-plugin的repackage目标。普通jar包只包含你写的class和资源文件双击或者java -jar跑会因为找不到依赖的库而报NoClassDefFoundError。repackage会把你项目依赖的所有第三方jar打进一个包并改写MANIFEST.MF指定Spring Boot自己的类加载器作为启动入口。所以打出来的jar通常比普通jar大一圈那是依赖在里面的体积。验证有没有打对解压jar看BOOT-INF/lib目录下是不是有一堆依赖jarMANIFEST.MF里是不是有Start-Class和Main-Class两行。少了这些说明plugin没生效检查pom里plugin有没有被注释掉。命令mvn clean package -DskipTests-DskipTests是跳过测试执行但仍然编译测试代码如果测试代码本身就编译不过用-Dmaven.test.skiptrue连编译都跳过。新手阶段可以先跳测试跑通流程再回来补。6.2 java -jar运行和配置外部化打包成功后target目录下会有一个项目名-版本号.jar命令行切到该目录java -jar demo-0.0.1-SNAPSHOT.jar看到和IDEA里一样的启动日志说明打包没问题。这时可以再验证一下外部配置覆盖java -jar demo-0.0.1-SNAPSHOT.jar --server.port9090启动后访问9090端口能通说明配置优先级生效了。这一步看似多余实际上很多线上部署问题就出在本地IDEA里能跑服务器上配置没覆盖到。如果生产环境要维护一份独立配置文件不放在jar里可以这样启动java -jar demo-0.0.1-SNAPSHOT.jar --spring.config.locationfile:./application-prod.yml注意路径要写对Windows和Linux的路径分隔符不一致脚本里最好用相对路径。到这里从IDEA建项目到命令行跑jar的完整链路就走完了。我个人在配这套环境时最大的体会是出问题别急着改代码。启动类的包位置、JDK版本、Maven配置这三处覆盖了新手阶段九成以上的启动失败。先花两分钟确认这三处比在代码里到处加打印日志快得多。另外IDEA的版本和SpringBoot的版本别跨太远一个刚发布的大版本配一个两三年前的IDE编辑器支持和构建行为都可能对不上这种问题最难查因为它看起来哪都没错。
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻