Spring Boot入门教程:60分钟快速上手

线上稳定吗
2025-12-15 07:44
阅读 333

大家好,我是老张,一个在杭州某国企混日子的后端程序员。每天早上9点打卡,下午5点半准时溜号,双休雷打不动——没错,就是那种让阿里网易的兄弟们又羡慕又不屑的“养老型”岗位。虽然项目节奏慢得像树懒走路,但咱也不能真躺平啊,毕竟35岁危机不是开玩笑的。

上周五下班前,领导突然扔给我一个活儿:“下周要给实习生做个Spring Boot培训,你写个入门材料吧,最好能60分钟带他们跑起来。”我当场就懵了:这玩意儿我天天用,但让我从零讲起?而且还要控制在一小时之内?行吧,谁让我是那个“文档写得最清楚”的老好人呢(其实是被测试和产品夸多了,不好意思推脱)。

趁着周末在家撸猫的间隙,我把这些年踩过的坑、熬过的夜、被线上Bug支配的恐惧都翻出来整理了一下。今天这篇,不整那些花里胡哨的理论,直接上实战经验,保证你看完就能搭个能跑的Springboot服务出来。


为啥非得是 Spring Boot?

先说句大实话:在我们这种传统企业,Java 项目以前都是用 Spring + MyBatis 手动搭架子,光配 XML 就能配到怀疑人生。记得去年双11前夕(对,我们国企也搞促销),运维大哥半夜打电话说“服务起不来”,我远程一看:ApplicationContext 初始化失败,原因是 dataSource 的 bean 名字拼错了……当时真的想砸电脑。

后来团队痛定思痛,全面转向 Spring Boot。最大的好处?约定优于配置。你不用再纠结 web.xml 怎么写、dispatcher-servlet 配哪儿,连 Tomcat 都给你内嵌好了。写个 main 方法,加个 @SpringBootApplication,直接 java -jar 跑起来——这对经常要写 POC(Proof of Concept)原型的我们来说,简直是救命稻草。

而且别看我们是国企,其实也在偷偷卷。隔壁组上个月刚用 Spring Boot + Vue 搞了个内部工单系统,前端用 Javascript 写页面,后端提供 REST API,前后端分离得明明白白。产品经理看了直呼“高端”,虽然他可能根本不知道 REST 是啥……


60分钟速成路线图

废话不多说,直接上干货。我们的目标很明确:60分钟内,从零搭建一个可运行的 Spring Boot 应用,并暴露一个 JSON 接口。全程使用 Java 17 + Maven + IntelliJ IDEA(如果你还在用 Eclipse,建议先升级下生产力工具 😏)。

第一步:创建项目(5分钟)

打开 start.spring.io —— 这个网站堪称 Spring Boot 的“脚手架生成器”。填几个关键信息:

  • Project: Maven
  • Language: Java
  • Spring Boot: 3.2.x(别用太老的版本,否则兼容性问题会让你哭)
  • Project Metadata:
    • Group: com.example
    • Artifact: demo
  • Dependencies(重点!):
    • Spring Web(必须!用来写接口)
    • Spring Data JPA(操作数据库)
    • H2 Database(内存数据库,开发时免装 MySQL)
    • Validation(参数校验)
    • Lombok(省掉 getter/setter,代码更清爽)

点击 “Generate”,下载 ZIP 包,解压后用 IDEA 打开。Maven 会自动下载依赖,喝口水的功夫就好了。

📌 国企小贴士:如果你公司网络屏蔽了外网,可以把这个 ZIP 提前下载好存到内网共享盘——我们组就这么干的,运维大哥再也不用半夜处理“依赖下载失败”的告警了。


第二步:写个 Hello World 接口(10分钟)

打开 DemoApplication.java,你会发现它已经有一个 main 方法了。现在我们在同级目录新建一个包 controller,然后创建 HelloController.java

package com.example.demo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    @GetMapping("/hello")
    public String sayHello() {
        return "Hello, Spring Boot! From 杭州国企摸鱼选手";
    }
}

注意两个注解:

  • @RestController = @Controller + @ResponseBody,直接返回 JSON 或字符串,不用再写 return ResponseEntity.ok().body(...)
  • @GetMapping@RequestMapping(method = GET) 的简写,语义更清晰

启动应用(直接运行 DemoApplication.main()),浏览器访问 http://localhost:8080/hello,看到那行熟悉的文字没?恭喜,你已经跨过了 80% 的初学者门槛!


第三步:加个数据库操作(20分钟)

光返回字符串太无聊了。我们来搞点真实的 CRUD。

1. 定义实体类

新建 entity/User.java

package com.example.demo.entity;

import jakarta.persistence.*;
import lombok.Data;

@Data // Lombok 自动生成 getter/setter/toString
@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String name;

    @Column(unique = true, nullable = false)
    private String email;
}

💡 注意:Spring Boot 3.x 默认用 Jakarta Persistence(不是 javax),所以是 jakarta.persistence.*,别导错包!

2. 写 Repository

新建 repository/UserRepository.java

package com.example.demo.repository;

import com.example.demo.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    boolean existsByEmail(String email);
}

Spring Data JPA 真的是神器——你只要继承 JpaRepository,就自动获得 save()findAll()deleteById() 等方法。自定义查询?方法名按规则写就行,比如 existsByEmail 会自动生成 SQL 判断邮箱是否存在。

3. 写 Service 和 Controller

为了代码可维护性(这也是我们组 code review 的重点),千万别把业务逻辑塞进 controller

// service/UserService.java
@Service
@RequiredArgsConstructor // Lombok 自动生成 final 字段的构造函数
public class UserService {
    private final UserRepository userRepository;

    public User createUser(String name, String email) {
        if (userRepository.existsByEmail(email)) {
            throw new IllegalArgumentException("Email already exists");
        }
        User user = new User();
        user.setName(name);
        user.setEmail(email);
        return userRepository.save(user);
    }
}

// controller/UserController.java
@RestController
@RequiredArgsConstructor
public class UserController {
    private final UserService userService;

    @PostMapping("/users")
    public User createUser(@RequestBody CreateUserRequest request) {
        return userService.createUser(request.getName(), request.getEmail());
    }

    @Data
    public static class CreateUserRequest {
        @NotBlank
        private String name;
        @NotBlank
        @Email
        private String email;
    }
}

这里用了 Validation 注解(@NotBlank, @Email),配合 @Valid 可以自动校验参数。不过为了简洁,我在 controller 里没写 @Valid,实际项目中一定要加上!


第四步:配置与调试(10分钟)

Spring Boot 默认读取 application.properties(或 yml)。我们来改点配置:

# application.properties
server.port=8081
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driver-class-name=org.h2.Driver
spring.jpa.hibernate.ddl-auto=create-drop
spring.h2.console.enabled=true
logging.level.com.example.demo=DEBUG

关键配置说明:

配置项 作用
server.port 改端口,避免和其他服务冲突
spring.jpa.hibernate.ddl-auto=create-drop 启动时建表,关闭时删表(仅开发环境用!生产环境必须设为 validatenone
spring.h2.console.enabled=true 开启 H2 控制台,访问 /h2-console 可查看内存数据库

⚠️ 血泪教训:去年有个实习生把 ddl-auto=create 用到了测试环境,上线当天把用户表清空了……项目经理脸都绿了。从此我们组的 CI/CD 流程里加了一条:禁止在非本地环境使用 create/create-drop


第五步:前后端联调(15分钟)

现在后端有了 /users 接口,前端怎么调?虽然我是后端,但基本的 Javascript 还是会写一点的(毕竟在杭州,不会点 JS 出门都不好意思打招呼)。

新建一个 index.html(放 resources/static/ 下,Spring Boot 会自动 serve):

<!DOCTYPE html>
<html>
<head>
    <title>User Creator</title>
</head>
<body>
    <input id="name" placeholder="Name">
    <input id="email" placeholder="Email">
    <button onclick="createUser()">Create</button>
    <pre id="result"></pre>

    <script>
        async function createUser() {
            const name = document.getElementById('name').value;
            const email = document.getElementById('email').value;
            
            const res = await fetch('/users', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ name, email })
            });
            
            const data = await res.json();
            document.getElementById('result').textContent = JSON.stringify(data, null, 2);
        }
    </script>
</body>
</html>

启动应用,访问 http://localhost:8081,填个名字和邮箱,点按钮——如果看到返回的 JSON,说明前后端打通了!🎉


生产环境避坑指南(来自国企老油条的经验)

虽然我们节奏慢,但该踩的坑一个没少。分享几个 实战经验

  1. 不要用 @Autowired 字段注入
    虽然方便,但不利于单元测试。推荐用 构造函数注入(配合 Lombok 的 @RequiredArgsConstructor 一行搞定)。

  2. 全局异常处理必须有
    新手常犯的错误:controller 里到处 try-catch。正确做法是用 @ControllerAdvice 统一处理:

    @RestControllerAdvice
    public class GlobalExceptionHandler {
        @ExceptionHandler(IllegalArgumentException.class)
        public ResponseEntity<ErrorResponse> handleIllegalArgument(IllegalArgumentException e) {
            return ResponseEntity.badRequest().body(new ErrorResponse(e.getMessage()));
        }
    }
    
  3. 日志别乱打
    我们组规定:INFO 级别只记录关键业务节点(如“订单创建成功”),DEBUG 才打详细参数。否则日志文件一天几个 G,运维大哥会提刀来找你。

  4. 健康检查接口要暴露
    加上 spring-boot-starter-actuator,开启 /actuator/health,K8s 或 Nginx 就能自动探活。我们去年上线新系统时,就靠这个避免了“假死”服务继续接收流量的事故。


最后说两句

60分钟说短不短,说长也不长。你可能还没完全理解自动配置原理、Starter 机制、AOP 切面这些高阶内容,但至少——你能跑起来一个结构清晰、可扩展、带数据库操作的 Spring Boot 应用了。

对我们这种“双休不加班”的国企程序员来说,技术不是炫技,而是稳定、可维护、少背锅。Spring Boot 正好满足这些需求:开箱即用、社区强大、文档齐全。就算哪天跳槽去阿里网易(听说那边 P7 以下都在卷 Spring Cloud),这套基础也完全够用。

哦对了,实习生培训那天,我特意加了一句:“如果你们觉得 Spring Boot 太简单,可以试试手写一个 Starter……” 结果全场沉默——看来,还是摸鱼香啊 😌

附:常用命令速查

# 打包
./mvnw clean package

# 运行
java -jar target/demo-0.0.1-SNAPSHOT.jar

# 指定配置文件
java -jar app.jar --spring.config.location=application-prod.yml

祝大家 coding happy,bug free!

评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝