SpringBoot项目搭建避坑指南:版本、配置与Docker部署实践

发布时间:2026/9/2 18:36:04

SpringBoot项目搭建避坑指南:版本、配置与Docker部署实践
简介这是一套面向Spring Boot初学者的简易综合示例工程基于MyBatis、Thymeleaf和Redis等组件覆盖视图解析、数据缓存、实时推送及定时任务等典型开发场景适合想了解Spring Boot常用整合方式的开发者对照学习。压缩包共71个文件以Java源码和编译后的class文件为主同时包含properties配置、HTML与FTL视图模板、XML映射文件以及少量CSS/JS脚本整体仅110KB结构紧凑便于按模块查看代码与配置。该资源已有191人学习属于轻量级入门示例可作为搭建Spring Boot基础框架时的参考。工程中直接展示了Freemarker与Thymeleaf两种视图解析的共存方式、MyBatis注解式SQL写法、Redis请求缓存配置以及WebSocket和Quartz/Scheduled定时任务的简单实现通过浏览这些代码读者可以快速梳理Spring Boot整合常用组件的基本思路减少自行摸索的时间。1. 环境版本怎么选项目没开工坑已经埋了两处1.1 先确认你的JDK版本再决定用哪个SpringBoot很多人习惯直接从网上复制一段依赖坐标结果项目创建完启动时报UnsupportedClassVersionError或者NoSuchMethodError然后开始怀疑代码有问题。其实这种问题八成出在版本匹配上。SpringBoot 的版本和 JDK 版本是强绑定关系。SpringBoot 版本基础框架版本最低 JDK 版本典型适配范围2.7.xSpring 5.3JDK 8大多数老项目、企业内部系统3.0.x ~ 3.2.xSpring 6.0JDK 17新项目、需要使用新特性的场景3.3.xSpring 6.1JDK 17当前比较稳定的 3.x 序列我见过太多人一上来就选最新版然后把 JDK8 的老代码迁过去碰到javax包全部变成jakarta一堆 import 错误。如果你只是想把 SpringBoot 项目跑起来或者做课程设计、公司内部工具最省事的组合是JDK 8 SpringBoot 2.7.18这是 2.x 系列最后的一个版本稳定且资料多遇到问题随便一搜就有答案。1.2 不要盲目追新版本热词里有个“springboot版本太高”说的就是从高版本退回低版本时踩的坑。SpringBoot 3.x 对新手并不算友好它对 JDK、内嵌容器、ORM 框架都有更高的要求。比如 3.x 里 SpringMVC 的路径匹配策略变了原来写web.statemachine这类配置的写法有些直接失效网上老教程的代码复制过来大概率跑不通。新手选版本的重心应该放在“能跑通、能学明白”上而不是“版本越新越强”。SpringBoot 2.7.18 足够覆盖绝大多数你目前会用到的东西。等你真的把一套项目完整开发过一遍再回头去对比 3.x 的差异会容易很多。1.3 Maven 环境里最容易被忽略的一个环节pom.xml 里引入依赖时绝大多数人会写这样的父工程声明parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version2.7.18/version relativePath/ /parent注意relativePath一定要保留成空标签如果它被删掉Maven 会去本地仓库找父工程找不到时会尝试从远程仓库下载整个项目环境解析速度会明显慢很多。另外依赖坐标里不需要写版本号版本统一由父工程管理。如果你在某次复制代码时手欠加上version字段很容易出现依赖冲突表现形式是启动时一堆ClassNotFoundException查起来相当痛苦。2. 用IDEA快速搭起第一个SpringBoot项目2.1 创建项目的关键选项IDEA 的 New Project 向导里选 Spring Initializr 以后真正会影响后续开发的就四个选项Group一般写公司域名倒序自己练习写com.example就行Artifact项目名比如demoJava 版本选你本机 JDK 的版本Packaging选 Jar不要选 War依赖部分只勾选一个Spring Web就能开始写了。很多人第一次创建的时候被一大堆依赖选项晃花眼什么 Security、Redis、MyBatis 全勾上结果项目启动就报一堆认证错误或者 Redis 没装直接连不上。少即是多先把一个接口跑通再逐步往里加东西。2.2 创建完以后目录上的坑项目创建出来后默认结构是这样的├── src/main/java/com/example/demo │ ├── DemoApplication.java │ └── controller/HelloController.java ├── src/main/resources │ └── application.properties或 application.yml ├── pom.xml这里面最容易踩的坑是把DemoApplication.java放在某一个代码子包里面比如放在com.example.demo.controller下面。SpringBootApplication 的默认扫描范围是它所在的包及子包一旦你把它放到一个角落子包里Controller 和 Service 就会找不到访问接口直接 404。我见过一个同学折腾了一下午一直以为是端口问题最后发现主类放错包了。更简单的验证方法启动时看控制台日志里有没有Tomcat started on port(s): 8080如果 Tomcat 正常启动了但接口 404优先看主类位置就对了。2.3 第一个接口的完整代码Controller 不需要往继承体系上套直接用注解就行RestController public class HelloController { GetMapping(/hello) public String hello() { return Hello, SpringBoot!; } }启动DemoApplication的 main 方法浏览器访问http://localhost:8080/hello能看到输出就说明这个项目已经通了。这一步简单但它是整个 SpringBoot 项目最基本的路径注解标注类、框架完成自扫描和映射、Tomcat 启动并响应请求。往后再复杂的功能本质上都是在这个路径上扩展出来的。3. 配置文件与常见小坑application.yml看起来简单其实最容易出错3.1 缩进错误会让你连启动都进不去application.yml比application.properties要直观所以绝大部分人喜欢用 yml。但 yml 对缩进极其敏感有时候你以为对齐了实际上前面的空格数量不对启动时直接报Found character that cannot start any token或者是mapping values are not allowed here。这种问题没有特别好的定位技巧唯一的建议就是写完后用 IDEA 自带的格式化功能重新排一下或者直接用application.properties。如果你是纯新手Properties 文件虽然没有树形结构那么好看但至少不会因为缩进挂掉。配置端口和上下文路径是最常用的两个server: port: 8080 servlet: context-path: /api加上context-path之后访问路径就变成http://localhost:8080/api/hello。这个配置在实际项目中非常常见因为它能让所有接口统一挂在一个前缀下方便网关转发和前端联调。3.2 IDEA 里 application.yml 不提示怎么解决热词里有“idea中springboot项目的application.yml不提示怎么办”这个我实测过很多次通常就三种原因项目还没引入对应的依赖。比如配置spring.datasource.url时没有添加数据库相关 starterIDEA 不知道你的类路径里有什么自然不提示。IDEA 的 Spring Boot 插件没启用。在 Settings - Plugins 里确认 Spring Boot 和 Spring 相关插件是打开状态。Maven 依赖没有正常加载。右下角弹提示时点一下Enable Auto-Import如果没弹手动刷新 Maven 工程。配置文件提示本质上依赖的是 IDE 与 Spring Boot 元数据文件的交互。如果你刚改完 pom.xml最好先让 Maven 下载完依赖再打开 yml 文件。不然你抱怨不提示的时候根本原因是依赖还没进本地仓库。3.3 Banner、多环境配置和热部署在线生成一个 Banner 放到src/main/resources/banner.txt启动的时候能看到漂亮的 ASCII 字符这个有点小乐趣但对实际开发帮助不大。真正重要的是多环境配置# application.yml spring: profiles: active: dev再建一个application-dev.yml里面写server.port: 8081建一个application-prod.yml写server.port: 8080。这样你本地开发、测试、生产只需要改动active一个属性就能切换整套配置。这个习惯要早点养成比在同一个 yml 文件里反复注释调端口要靠谱得多。热部署方面加一个 devtools 依赖改完代码可以自动重启应用。但在 IDEA 里需要勾选Build project automatically才生效我一般不太建议新手依赖这个因为有时候热部署并没有真正触发你等半天发现接口还是老逻辑还不如手动Ctrl F9来得干脆。4. 自动装配与Starter把SpringBoot当黑箱用可以但面试不能黑箱答4.1 Starter 是什么它到底做了什么spring-boot-starter-web这串东西看起来只是一个普通依赖但它的本质是“集中管理依赖 自动配置”。你引入它之后框架会自动完成以下动作把 SpringMVC 相关 jar 包全部加进来、注册 DispatcherServlet、创建内嵌 Tomcat、配置默认的 JSON 序列化器等。这意味着你只需要写一个RestController什么都不用配就能对外提供服务。也正是因为这种机制“为什么你只是加了一个依赖所有功能就都能用了”才会成为面试常考题。在 SpringBoot 2.7 及之后的版本里候选配置类的列表文件已经换到了META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports以前放在spring.factories里的那些自动配置类现在逐步迁移到这个新文件里。如果你自己写一个 Starter 和自动配置类需要遵循这套新的发现机制。4.2 组合注解背后的条件装配逻辑SpringBootApplication实际上是三个注解的组合SpringBootConfiguration本质上是 Configuration标记这是个配置类EnableAutoConfiguration开启自动配置ComponentScan包扫描其中最核心的是EnableAutoConfiguration它负责加载候选配置类。但 SpringBoot 不会无条件加载所有配置每个配置类内部都有大量条件注解。比如ConditionalOnClass只有你这个项目引入了某个类才会执行接下来的配置ConditionalOnMissingBean如果容器里已经有你自定义的 Bean就不会覆盖这就能解释一个现象你自己手动声明了一个 DataSource框架就不会再帮你创建匿名数据源。这个设计避免了用户配置和自动配置冲突也是 SpringBoot“约定优于配置”的关键基础。4.3 循环依赖高版本已经默认禁止了热搜里“springboot 循环依赖”出现频率很高指的是两个类互相注入对方Spring 无法决定谁来先创建。在 SpringBoot 2.6 之前字段注入能通过三级缓存绕过去从 2.6 开始spring.main.allow-circular-references默认是 false循环依赖直接启动失败。这里有两条路可以走最简单粗暴在 yml 里加上spring.main.allow-circular-references: true正确做法重新设计代码结构把相互依赖的部分抽到一个新的服务里我建议你尽量走第二条路。循环依赖在单体小项目里还能忍一旦拆成微服务或模块化结构这种设计就是灾难。面试官问这个问题的时候真正想听到的其实是你知道它不对也知道该怎么改。5. 打包部署从本地运行到Docker Desktop5.1 打成可执行 jar 包SpringBoot 自带 Maven 插件pom.xml 里默认已经声明好了plugin groupIdorg.springframework.boot/groupId artifactIdspring-boot-maven-plugin/artifactId /plugin在 IDEA 右侧的 Maven 面板里执行clean再package或者直接在终端跑mvn clean package打包完成后jar 包会生成在target目录下java -jar target/demo-0.0.1-SNAPSHOT.jar这里要区分一个概念SpringBoot 打的包是 fat jar里面自带内嵌 Tomcat不需要在外面再装一个 Tomcat。很多人第一次部署时习惯把 war 包扔到外部 Tomcat 里反而出问题。5.2 自己写一个可用的 Dockerfile如果你是想把 JDK8 的项目打包到 Docker DesktopDockerfile 可以这样写FROM openjdk:8-jdk-alpine WORKDIR /app COPY target/demo-0.0.1-SNAPSHOT.jar app.jar EXPOSE 8080 ENTRYPOINT [java, -jar, app.jar]有两个细节值得注意。第一8-jdk-alpine这个镜像比较精简但个别旧版项目在里面跑会缺一些系统依赖比如字体相关包。如果你遇到莫名其妙的运行错误可以换成openjdk:8-jdk或者eclipse-temurin:8-jdk体积大一些但更省心。第二容器里的时区和编码问题。很多项目在本地正常打进 Docker 后日志时间差了 8 小时是因为容器默认使用 UTC 时区。建议在 Dockerfile 里加上ENV TZAsia/Shanghai字符编码方面最好统一在 pom.xml 里设置project.build.sourceEncoding为 UTF-8否则中文日志或接口返回有可能乱码。5.3 构建镜像并启动验证按顺序执行命令docker build -t springboot-demo . docker run -d -p 8080:8080 --name demo-app springboot-demo然后用浏览器访问http://localhost:8080/hello。如果访问不了先看容器是否还在运行docker ps -a docker logs demo-app日志是排查这类问题的第一手段。端口被占用、镜像平台不匹配比如 Apple Silicon 上跑 x86 的 JDK8 老镜像、启动失败后容器自动退出这些在日志里都能看到线索。尤其是 Apple Silicon 场景如果提示exec format error八成是镜像和本机 CPU 架构不匹配需要加--platform linux/amd64或者在 Maven 打包时注意 JDK 版本。我个人在实际操作中的体会是第一次用 Docker 部署 SpringBoot 项目不要想着一次成功。你先保证本地java -jar能跑起来再上 Docker这样能快速隔离“代码有问题”和“镜像有问题”两类故障。等这一套流程跑顺了再去思考微服务、配置中心这些东西节奏会稳很多。本文还有配套的精品资源点击获取

相关新闻

CPU三级缓存技术解析:U270K与U400系列选购指南

CPU三级缓存技术解析:U270K与U400系列选购指南

2026/9/2 18:36:04

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

AI流量革命:从人类浏览到机器处理,技术架构如何应对千倍冲击

AI流量革命:从人类浏览到机器处理,技术架构如何应对千倍冲击

2026/9/2 18:26:03

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

AI音频源分离实战:用开源工具制作保留和声的伴奏

AI音频源分离实战:用开源工具制作保留和声的伴奏

2026/9/2 18:26:03

很多做翻唱、混音或视频配乐的朋友,都会遇到一个尴尬情境:网上找到的伴奏要么只有纯鼓点,要么原声残留太明显,尤其当你想保留歌曲里那几句很漂亮的背景和声时,普通“一键去人声”的软件几乎无能为力。最近在为 Epik Hi…

Tensor 里的数据到底是怎么组织的?——Shape、Axis、Batch 一篇讲清

Tensor 里的数据到底是怎么组织的?——Shape、Axis、Batch 一篇讲清

2026/9/2 20:56:10

上一篇我们已经知道:深度学习模型真正处理的,是一块一块的 Tensor。但仅仅知道 Tensor 是什么,还远远不够。真正开始接触 PyTorch 后,很快就会遇到:x.shape x.ndim x.reshape(...) x.unsqueeze(...) x.permute(...)以及…

资源站源码选型与部署实战:PHP建站、SEO优化到长期运营

资源站源码选型与部署实战:PHP建站、SEO优化到长期运营

2026/9/2 20:56:10

简介:这是一套基于ASP的完整免费资源站源码,面向网站开发初学者、快速建站用户及二次开发者,可帮助快速搭建并理解完整站点。压缩包内包含完整的前端页面、服务端脚本、数据库配置及样式交互文件,共包含1119个相关文件&#xff0c…

AI视频剪辑工作流:语音转文字与提示词驱动的粗剪实战

AI视频剪辑工作流:语音转文字与提示词驱动的粗剪实战

2026/9/2 20:56:10

在实际的视频剪辑流程中,AI剪视频并不是某一款软件里一个神秘的“一键生成”按钮。真正关键的是你喂给它多少有效信息,以及怎样把语音转文字、AI粗剪、字幕生成、音频处理这些能力按顺序组合起来。很多人卡在中间,不是因为工具不会用&#xf…

绝地潜兵2外观替换MOD安装指南:以VRCChocolateShibuyaMaji为例

绝地潜兵2外观替换MOD安装指南:以VRCChocolateShibuyaMaji为例

2026/9/2 20:56:10

《绝地潜兵2》装备外观类MOD里,像“VRCChocolateShibuyaMaji替换IE-12DS-42”这种命名方式,第一眼容易让人懵。它实际做的事情很直接:把游戏里原本的IE-12和DS-42这两件装备外观,替换成一套以VRCChocolateShibuyaMaji为代号风格的…

Acknowledge 4.2振动测试软件安装配置指南:从驱动到模态分析实战

Acknowledge 4.2振动测试软件安装配置指南:从驱动到模态分析实战

2026/9/2 20:56:10

简介:Acknowledge4.2安装包是一款专为科研、工程与教学场景打造的科学数据采集与分析软件,支持数据采集卡、示波器、信号发生器等多类硬件设备接入,能够实时捕获并记录模拟或数字信号,解决复杂数据的采集与预处理问题。压缩包共63…

电脑弹窗广告怎么彻底关闭?按来源分类逐个设置

电脑弹窗广告怎么彻底关闭?按来源分类逐个设置

2026/9/2 20:46:09

右下角突然冒出一个弹窗,正在写文档或者打游戏的时候被它挡住半屏,那种烦躁感想必很多人都体会过。想找关闭按钮,往往要找半天,有时一着急还误点进去,跳到某个不知名的页面。等你退回来,弹窗已经重新弹了出…

备战数据库管理工程师校招:索引、事务、备份恢复核心考点解析

备战数据库管理工程师校招:索引、事务、备份恢复核心考点解析

2026/9/2 10:08:07

每年校招季我都会接触不少准备数据库方向笔试的同学,看到最多的状态就是:简历上写着“熟悉 MySQL”“了解索引优化”,一碰到数据库管理工程师的笔试卷,却在索引、事务、锁、备份恢复这些题目上翻车。网易这套 2018 校园招聘数据库…

数字电路时序基石:深入理解建立时间与保持时间

数字电路时序基石:深入理解建立时间与保持时间

2026/9/2 12:11:52

1. 这不是“背公式”的事:时间参数到底在约束什么你翻过数字电路教材,一定见过这两个词:建立时间(Setup Time)和保持时间(Hold Time)。它们常被并列写在触发器(Flip-Flop&#xff09…

蓝桥杯国赛超声波测距机:从单片机原理到嵌入式系统实战

蓝桥杯国赛超声波测距机:从单片机原理到嵌入式系统实战

2026/9/1 23:49:08

1. 项目缘起:从赛题到超声波测距机的诞生第八届蓝桥杯单片机设计与开发国赛的题目,我至今记忆犹新。它没有直接给出一个花哨的名字,而是用“超声波测距机”这个朴实无华的功能描述,精准地勾勒出了考核的核心。对于当时备赛的我而言…

单片机毕业设计-基于单片机与蓝牙通讯的输液状态监测终端设计与开发 基于 STM32 或 51 单片机的液位‑滴速‑温度多参数输液监护装置设计(024005)

单片机毕业设计-基于单片机与蓝牙通讯的输液状态监测终端设计与开发 基于 STM32 或 51 单片机的液位‑滴速‑温度多参数输液监护装置设计(024005)

2026/9/2 0:04:59

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机,Java、小程序技术领域和毕业项目实战 ✌️…

DeepSeek字幕翻译实战:从API调用到批量SRT转中文的完整方案

DeepSeek字幕翻译实战:从API调用到批量SRT转中文的完整方案

2026/9/2 0:04:59

这次我们来看一个很实用的 DeepSeek 落地场景:用 DeepSeek 把英文视频字幕自动翻译成中文。具体案例是《恶魔君》1989 年第 28 集的英转中字幕任务,标题写得很直白,但背后其实是一整套可以复用的技术流程:字幕解析、模型调用、批量…

用Python搭建搞笑语音助手:从语音识别到语音合成全教程

用Python搭建搞笑语音助手:从语音识别到语音合成全教程

2026/9/2 0:04:59

当你家里摆着一台天猫精灵,却总希望语音助手偶尔“不正经”一点,不用官方腔回答问题,而是张口就接几句搞笑段子,会是什么体验?我最近动手验证了一下这个想法——没有去改装任何市面上现有的智能音箱,而是直…

远程协作的工作台整理

远程协作的工作台整理

2026/9/2 6:21:32

远程协作的工作台整理远程协作的核心不是再加一个工具,而是让交接信息足够完整。异步任务要写明目标、输入位置、完成标准和需要决策的人。 工作台的最小配置 将日程、待办、代码和沟通入口收拢到少数固定位置;通知按紧急程度分层。工作台不需要模仿办公…

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

2026/9/2 6:21:32

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

2026/9/2 2:45:06

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…