发布时间:2026/9/2 18:36:07
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这样能快速隔离“代码有问题”和“镜像有问题”两类故障。等这一套流程跑顺了再去思考微服务、配置中心这些东西节奏会稳很多。本文还有配套的精品资源点击获取

相关新闻

2026/9/2 18:36:07

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

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

2026/9/2 18:31:07

技术选型决策:Opus 5与Fable 5的评估框架与实践指南

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

2026/9/2 18:31:07

多模态感知融合实战:从概念到代码构建通用机器人感知系统

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

2026/9/2 18:51:09

UE5中用Niagara Ribbon实现近战武器轨迹拖尾效果

很多做近战战斗系统的朋友应该都有同感:角色攻击动画调得再顺,如果挥刀时手上没有任何视觉反馈,玩家就会觉得这一刀“空空的”,像是打在空气上。反过来,只要在武器划过的地方补一条干净利落的轨迹光效,攻击…

2026/9/2 18:51:09

阵营九宫格与印象坐标:构建角色关系创作坐标系

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

2026/9/2 18:51:08

STM32F105 USB自定义协议工程开发实战解析

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

2026/9/2 18:51:08

C#算数运算符详解:从基础运算到类型转换与避坑指南

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

2026/9/2 18:46:08

AI叙事提示词拆解:从分镜脚本到TTS配音的完整生成管线

如果现在拿到这样一句话——“五岁时,我就立刻被西班牙人剪了朋克头发,当时我愁眉苦脸,被送到了欧洲演戏Leon,结果正当我与杀手里昂产生了感情时,娜塔莉波特曼将我替换了下来,下半部由她主演”——你会怎么…

2026/9/1 16:02:17

vSound小提琴数字处理器实操指南:从接线到演出的完整配置

电小提琴或者原声小提琴插电演出,第一个绕不开的坎就是声音难听。原声琴的共鸣和空气感一旦进了拾音器,出来的往往是一坨干瘪、发尖、带着奇怪塑料味的信号。我当初第一次把琴接上乐队调音台,直接被主唱吐槽"你这声音像在锯钢丝"。…

2026/9/2 9:00:32

传感器接口IC如何攻克生物化学传感的微弱信号难题?

1. 从电极到比特流:为什么生物化学传感必须依赖专用接口IC 做生物化学传感的人都有过类似的经历:明明传感器本身性能很好,信号输出却一塌糊涂——噪声大、漂移明显、重复性差,怎么调都达不到预期。很多时候问题并不在传感器&#…

2026/9/2 8:41:06

STM32F411CEU6多通道ADC采集:扫描模式+DMA实现详解

1. 多通道 ADC 的用武之地把“Multichannel ADC”和“STM32F411CEU6”这两个关键字放在一起,其实就是嵌入式开发里最常遇到的一类需求:用一块不算贵的 MCU,同时采集多路模拟信号。STM32F411CEU6 是 48 引脚的 Cortex-M4F 主控,主频…

2026/9/2 0:03:41

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

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

2026/9/2 0:03:41

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

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

2026/9/2 0:03:41

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

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

2026/9/2 1:15:22

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/2 1:15:22

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/2 1:15:20

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…