从零搭建一个SpringBoot项目的完整步骤

发布时间:2026/8/21 12:11:44
从零搭建一个SpringBoot项目的完整步骤
先别急着打开IDE。搭建SpringBoot项目最容易被忽视的环节恰恰发生在你敲下第一行代码之前——你如何选择构建工具、如何组织包结构、如何配置依赖版本这些看起来不起眼的决定会在三个月后项目复杂到连你自己都不想维护时变成救命稻草或致命毒药。所以这篇文章讲的不是“生成下一个项目”而是“如何有意识地搭建一个能陪你走很远的项目”。前提你的机器上到底该装什么如果你以为只需要JDK就行那是对SpringBoot生态的误解。JDK本身是地基但不是全部。我建议你至少准备以下三样东西JDK 17或21Oracle或OpenJDK均可版本别用8了Spring Boot 3.x强制要求17Maven 3.9 或 Gradle 8.x二选一大多数人选Maven但Gradle的构建速度会让你上瘾一个你顺手且有良好插件生态的IDEIntelliJ IDEA Community版就够了有些教程还会让你装Lombok插件、Spring Assistant等但那些都是锦上添花。你真正需要的是一个能让你专注写代码而不是折腾环境的最小集合。装好之后在终端里运行java -version、mvn -v确认版本输出无误再继续往下走。第一步选择初始化方式而不是从空白目录开始很多人喜欢在IDE里新建一个“Empty Project”然后手动创建目录、写pom.xml。这不叫从零这叫折磨自己。正规的“从零”也分两种路线使用Spring Initializr网页版或IDE内置版使用Spring Boot CLI 或curl命令直接生成我个人推荐上面第一种因为它能让你通过勾选依赖的方式从一开始就建立“依赖管理”的意识。访问start.spring.io填写Group一般用公司域名反写比如com.example、Artifact项目名比如demo-api。Build选择MavenLanguage选择JavaSpring Boot版本选最新的稳定版比如3.3.x。其他选项先别碰包括依赖那一栏也先留空。记住初始依赖越少你对项目的掌控力越强。之后再按需“做加法”而不是把一堆用不上的starter拉进来让启动时间和包体积都变得难看。第二步把生成的项目导入IDE之前先看一眼目录结构下载下来的zip解压后你会看到这样的结构demo-api/ ├── pom.xml ├── src/main/java/com/example/demoapi/ │ └── DemoApiApplication.java └── src/main/resources/ └── application.properties先别急着双击DemoApiApplication.java。用文本编辑器打开pom.xml看几行关键内容。凡是你不理解的依赖就应该立即去查而不是等报错再回头。比如那个spring-boot-starter-test里面包含JUnit5、AssertJ、Mockito等测试库它不是框架本身但会让你的测试体验顺畅得多。另外注意src/main/resources下没有static和templates目录这是因为你还没添加Web相关依赖。当你在Initializr上勾选Spring Web后这两个目录也不会帮你创建——它们要等你写了Controller并实际运行静态资源时才存在意义。别慌这是正常现象。第三步添加第一份业务依赖——Spring Web打开pom.xml在dependencies标签里加入dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency然后让Maven重新加载。你会发现项目里多了一堆包其中就包含内嵌的Tomcat服务器。理解“内嵌”这两个字是理解SpringBoot精髓的一半。你不需要单独安装Tomcat也不再需要把项目打成war包扔进外部容器只需要运行一个包含main方法的Java程序HTTP服务就起来了。写一个最简单的Controller来验证package com.example.demoapi.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; RestController public class HelloController { GetMapping(/hello) public String hello() { return Hello from Spring Boot!; } }这里用到了两个注解RestController和GetMapping。注解不是SpringBoot的发明但SpringBoot把注解的使用体验推到了极致——你不需要写任何XML配置类上的注解就是配置本身。运行主类DemoApiApplication等控制台出现 “Tomcat started on port 8080”然后用浏览器访问http://localhost:8080/hello。看到那串字符串时恭喜你一个从零搭建的SpringBoot项目已经拥有了最有说服力的“第一口呼吸”。第四步配置文件的演进——从properties到YAML项目里默认生成的是application.properties空白的什么都没写。你当然可以直接在里面写server.port8081但我会建议你把它改成application.yml因为YAML的层级结构更适合表达复杂配置而且SpringBooot对两种格式都支持。怎么改删掉旧文件新建同名.yml内容写server: port: 8081重启应用端口变成8081。就这么简单。接着你可能想配置数据库连接、Redis、日志级别等每个配置项都会考验你对“约定优于配置”的信任程度。SpringBoot的配置体系本质上是一套“按需覆盖”的机制框架给了你默认阈值你只要在配置文件里覆盖你想改的那一小部分即可。但注意别把配置文件当成垃圾箱。多环境配置是你迟早要面对的第一道坎。举个经典场景本地用H2内存数据库测试用MySQL生产用PostgreSQL。你可以在application.yml旁边创建application-dev.yml、application-prod.yml然后通过spring.profiles.activedev来切换。这不算高级技巧却是很多从零开始的新手最容易漏掉的架构决策。第五步搭建分层的包结构而不是把所有类塞进一层把Controller、Service、Repository全部放在同一个包下项目小的时候毫无问题但一旦业务逻辑复杂拆分成本会成指数级增长。我推荐的基础分层是com.example.demoapi/ ├── DemoApiApplication.java ├── controller/ # HTTP层只负责参数接收和响应封装 ├── service/ # 业务逻辑层实现具体规则 ├── repository/ # 数据访问层与数据库交互 ├── entity/ # 数据库映射实体 ├── dto/ # 请求和响应对象避免实体直接暴露 └── config/ # 配置类如安全、拦截器、异步线程池包名不是装饰而是团队代码思维的肌肉记忆。当你新增一个接口时先在脑海中规划它属于哪个层再动手写类。如果你发现一个Controller超过200行或者一个Service里同时处理着数据校验、权限判断、消息发送和日志记录那就说明分层已经失衡了。有人会问initializr生成的主类DemoApiApplication明明放在最外层为什么要单独放一个包因为主类在application包下SpringBoot会默认扫描主类所在的包及其子包。这个默认行为是“潜规则”你必须从一开始就把主类放在根包下面否则后续的Component、Service、RestController全都会因扫描不到而失效报出让人摸不着头脑的404。第六步配置一个能用的数据库别用H2做死忠粉很多教程会让新手先集成H2内存数据库因为它零配置。但是H2只能作为开发期的临时选项它在Sql语法和生产环境行为上的差异足以让你在发布前一夜惊出一身冷汗。我更推荐从第一步就接上MySQL或PostgreSQL。以MySQL为例在application.yml中添加数据源配置spring: datasource: url: jdbc:mysql://localhost:3306/demo username: root password: yourpassword driver-class-name: com.mysql.cj.jdbc.Driver jpa: hibernate: ddl-auto: update show-sql: true在pom.xml中加入mysql-connector-j和spring-boot-starter-data-jpa。然后创建Entity和RepositoryEntity public class User { Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id; private String name; // getter/setter省略 }public interface UserRepository extends JpaRepositoryUser, Long { }写一个Service调用Repository。整个过程没有一条SQL语句也不需要手写连接池配置。SpringBoot把你从JDBC的重复劳动中解放出来但代价是你要背下“命名规则”和“关联映射”的约定。比如findByName这个方法如果字段名写成了userName方法名就得是findByUserName而不是findByUsername这种大小写敏感的错误恰恰是最常见的新手坑。第七步统一返回格式和全局异常处理等到你的Controller开始返回数据你才会意识到一个裸返回的String或User对象是远远不够的。前端需要知道“这次请求成功没数据是什么出错了是什么原因”于是你写一个统一的ResultT类public class ResultT { private Integer code; private String message; private T data; // 省略构造、getter/setter }再定义一个全局异常处理器RestControllerAdvice public class GlobalExceptionHandler { ExceptionHandler(BusinessException.class) public ResultString handleBusinessException(BusinessException e) { return Result.error(e.getCode(), e.getMessage()); } }这就是从零到“可用”的关键一跃。全局异常处理不是可选项它是生产级项目的标配。因为默认情况下异常会返回一堆堆栈信息给前端或者更糟——直接把服务器上的文件路径和数据库结构泄露出去。用RestControllerAdvice把异常拦截下来转成统一的JSON结构无论对前端还是后端都是双赢。第八步写测试别等上线前再补通过spring-boot-starter-test你可以非常方便地做集成测试SpringBootTest AutoConfigureMockMvc class DemoApiApplicationTests { Autowired private MockMvc mockMvc; Test void testHello() throws Exception { mockMvc.perform(get(/hello)) .andExpect(status().isOk()) .andExpect(content().string(containsString(Hello))); } }测试从零搭建项目的第一天写起并不是浪费时间而是给你的项目装上安全网。后续每加一个功能每改一次数据库字段跑一遍测试就能瞬间确认没有破坏旧逻辑。很多人觉得写测试麻烦其实更麻烦的是手动用Postman一遍遍点点到最后自己都忘了测过哪些接口。第九步日志和热部署是效率放大器在application.yml里写logging: level: com.example.demoapi: debug然后在pom.xml加上spring-boot-devtoolsoptional为true。devtools包含两个超棒的副作用一是代码变更后自动重启二是对页面模板的热加载。热部署不是懒人福音而是程序员心流的守护者。每次改一行代码就要手动重启十秒钟你的专注力就碎十次一天下来根本没法进入深度开发状态。至于日志别再用System.out.println了。用SLF4J的LoggerFactory在类上声明private static final Logger log LoggerFactory.getLogger(Xxx.class)然后在关键分支写log.info()和log.error()。日志不是你写代码时给机器看的批注它是你系统运行时的“黑匣子”一旦线上出了Bug日志就是第一手证据。第十步实际部署时打包方式决定你的交付体验SpringBoot项目默认打包成可执行jar你只需要在pom.xml里确保有spring-boot-maven-plugin然后执行mvn clean package。生成的目标jar在target目录下用java -jar demo-api-0.0.1-SNAPSHOT.jar就能启动。但“from zero to production”还差最后一步——环境变量。把配置里的密码、密钥、数据库地址统统用${DB_URL}占位符替代然后通过启动命令传入java -jar demo-api.jar --spring.profiles.activeprod --DB_URLjdbc:mysql://prod-server:3306/demo这样做的意义在于你不需要为“开发环境”“测试环境”“生产环境”各维护一份配置文件。一份代码多个环境通过变量注入区分。配置与代码分离是SpringBoot项目从“能跑”走向“可靠”的标志。别把这篇文章当作终点而要当作起点搭建一个SpringBoot项目的确有固定的套路但套路背后是无数工程经验的凝结。从选择依赖开始到包结构、配置文件、异常处理、测试、日志、部署每一步看似平淡实则在回答同一个问题你希望这个项目在三个月后、一年后依然能被自己和同事轻松理解吗不要把“从零搭建”理解为“把每一步背熟”。真正的理解在于当你看到某个错误堆栈时你能判断出它是配置的问题、依赖冲突的问题还是代码逻辑的问题。今天你创建了一个能返回Hello的项目明天你要让它能在高并发下稳定运行后天你要让它能优雅地集成各种中间件。从零到一不难难的是在一之上不断叠加正确的抽象而不是在混乱中修补漏洞。下次当你打开Spring Initializr时建议你多想想这每一步的选择究竟是在减少未来的麻烦还是在为将来的自己挖坑最好的SpringBoot项目是那些让你几乎感受不到SpringBoot存在却始终保持着清晰结构和可预测行为的项目。动手写吧错误会告诉你哪里需要调整而调整的过程才是真正的成长。