Spring Boot入门教程:60分钟快速上手
大家好,我是老K。前某中型电商公司的技术总监,现在已经从996的牢笼里跳出来,在成都这座“巴适得板”的城市准备搞自己的小创业项目。每天早上8点准时泡上一壶茉莉花茶,打开VS Code,开始写代码——不是为了赶双11大促的上线 deadline,而是为了自己真正想做的东西。
上周五晚上,我一边刷BOSS直聘(别笑,简历还在悄悄更新),一边翻自己以前写的项目,突然想起一个事儿:去年带新人的时候,有个实习生问我:“K哥,Spring Boot到底怎么用啊?我看网上教程要么太浅,要么直接上微服务、Nacos、Sentinel那一套,头都大了。” 当时我随口回了句“照着官方文档走就行”,结果那小子三天后跑来跟我说:“K哥,你这‘照着走’三个字,差点让我在公司过夜。”
于是今天,趁着创业还没正式开干、咖啡还没凉,我决定写一篇真正能60分钟上手的Spring Boot实战教程。不讲八股文,不堆概念,就聚焦一件事:让你写个能跑起来的后端接口,顺便还能爬点数据玩玩。
为啥要结合爬虫?因为我自己最近就在用Go写一个竞品监控工具(对,就是那种偷偷看对手价格变没变的玩意儿),但有些轻量级任务,用Java+Spring Boot反而更快搭原型。而且,很多同学学Spring Boot就是为了做毕设或者加到简历里充门面——那不如直接做个带爬虫功能的API服务,面试时还能多聊两句。
背景:为什么是现在?
去年双11前,我们团队被产品经理逼着三天内上线一个“商品舆情分析”模块。需求很简单:抓取某宝评论,分析情绪。当时我第一反应是“用Python啊!”,但运维老王一脸苦相:“K哥,Python服务部署起来太麻烦了,日志、监控、告警全要单独配,能不能用Java?咱们K8s集群都是Java应用……”
行吧,那就Spring Boot。结果发现,其实用Spring Boot写个HTTP爬虫服务,比想象中简单得多。而且性能还行——毕竟Netty底子在那儿。
所以这篇教程的核心目标很明确:
- 60分钟内,用Spring Boot搭建一个RESTful API服务
- 集成一个简单的网页爬虫(比如抓取某个公开页面)
- 能把数据存到数据库(哪怕只是H2内存库)
- 最终打包成jar,本地能跑,部署也不慌
准备工作:别被环境劝退
先确认你装了这些:
- JDK 17(别问为啥不是8,2024年了兄弟)
- Maven 或 Gradle(我用Maven,但Gradle党也别急,差别不大)
- 一个IDE(IntelliJ IDEA 社区版就行,别再用Eclipse了,真的)
- Postman 或 curl(测试接口用)
然后,去 https://start.spring.io 生成项目。我选的配置如下:
| 选项 | 值 |
|---|---|
| Project | Maven |
| Language | Java |
| Spring Boot | 3.2.x |
| Group | com.example |
| Artifact | springboot-crawler-demo |
| Dependencies | Spring Web, Spring Data JPA, H2 Database, Lombok |
Lombok 是个好东西,省掉一堆getter/setter。别听那些“影响可读性”的老古董BB,现代Java开发没Lombok就像吃火锅不蘸油碟——难受。
点击“Generate”,下载zip,解压导入IDE。搞定,项目骨架就有了。
第一步:写个Hello World,先让服务跑起来
打开 DemoApplication.java,它长这样:
@SpringBootApplication
public class SpringbootCrawlerDemoApplication {
public static void void main(String[] args) {
SpringApplication.run(SpringbootCrawlerDemoApplication.class, args);
}
}
没错,就这。现在直接运行 main 方法,你会看到控制台输出:
Tomcat started on port(s): 8080 (http)
访问 http://localhost:8080,应该会返回404——正常,因为我们还没写任何接口。
新建一个Controller:
@RestController
@RequestMapping("/api")
public class HelloController {
@GetMapping("/hello")
public String sayHello() {
return "Hello from Chengdu! ☕️";
}
}
重启,访问 http://localhost:8080/api/hello,看到那句成都问候,恭喜你,Spring Boot服务跑起来了!
划重点:
@RestController=@Controller+@ResponseBody,直接返回JSON或字符串,不用写视图层。我们做API服务,基本都用这个。
第二步:加个爬虫,别光说不练
现在,我们要实现一个接口:GET /api/crawl?url=xxx,传入一个URL,返回该页面的标题。
先加依赖。编辑 pom.xml,加上Jsoup(Java里最友好的HTML解析库):
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.17.2</version>
</dependency>
然后写爬虫逻辑:
@Service
@Slf4j // Lombok注解,自动注入logger
public class WebCrawlerService {
public String extractTitle(String url) {
try {
Document doc = Jsoup.connect(url)
.userAgent("Mozilla/5.0 (compatible; CrawlerBot/1.0)")
.timeout(5000)
.get();
return doc.title();
} catch (IOException e) {
log.error("Failed to crawl URL: {}", url, e);
throw new RuntimeException("Crawl failed: " + e.getMessage());
}
}
}
再写个Controller调用它:
@RestController
@RequestMapping("/api")
@RequiredArgsConstructor // Lombok自动生成构造函数注入
public class CrawlController {
private final WebCrawlerService crawlerService;
@GetMapping("/crawl")
public ResponseEntity<Map<String, String>> crawl(@RequestParam String url) {
String title = crawlerService.extractTitle(url);
Map<String, String> result = Map.of("url", url, "title", title);
return ResponseEntity.ok(result);
}
}
启动服务,试试:
curl "http://localhost:8080/api/crawl?url=https://www.zhihu.com"
如果返回类似:
{"url":"https://www.zhihu.com","title":"知乎 - 有问题,就会有答案"}
那就说明爬虫跑通了!注意:有些网站会反爬(比如加验证码、限流),这里只是演示原理。生产环境请遵守robots.txt,别乱爬!
吐槽一句:之前有个测试同事拿这个接口去爬我们自家后台,结果触发了风控,运维半夜打电话问我“谁在DDoS?”——我当时真的想砸电脑。
第三步:把数据存下来,简历才有料
光爬不存,等于白干。现在加个实体,把每次爬取记录存到数据库。
先定义Entity:
@Entity
@Table(name = "crawl_record")
@Data // Lombok:getter/setter/toString等
@NoArgsConstructor
@AllArgsConstructor
public class CrawlRecord {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String url;
private String title;
private LocalDateTime crawledAt;
}
Repository接口(Spring Data JPA的魔法):
public interface CrawlRecordRepository extends JpaRepository<CrawlRecord, Long> {
}
修改Service,保存记录:
@Service
@Slf4j
@RequiredArgsConstructor
public class WebCrawlerService {
private final CrawlRecordRepository recordRepo;
public String extractTitle(String url) {
try {
Document doc = Jsoup.connect(url)
.userAgent("Mozilla/5.0")
.timeout(5000)
.get();
String title = doc.title();
// 保存记录
CrawlRecord record = new CrawlRecord();
record.setUrl(url);
record.setTitle(title);
record.setCrawledAt(LocalDateTime.now());
recordRepo.save(record);
return title;
} catch (IOException e) {
log.error("Crawl failed for URL: {}", url, e);
throw new RuntimeException("Crawl error: " + e.getMessage());
}
}
}
重启应用,再调一次 /api/crawl,然后访问H2控制台:
- 浏览器打开
http://localhost:8080/h2-console - JDBC URL 填
jdbc:h2:mem:testdb - 用户名
sa,密码留空 - 点击 Connect
执行 SELECT * FROM crawl_record;,就能看到你的爬取记录!
小贴士:H2是内存数据库,重启就丢数据。但作为开发阶段的快速验证,足够了。真要上线,换成MySQL或PostgreSQL,只需改两行配置(后面说)。
第四步:配置优化 & 生产准备
虽然我们目标是60分钟上手,但别把demo当生产。这里分享几个我在职时踩过的坑:
1. 配置文件别硬编码
application.yml 里加点配置:
app:
crawler:
timeout: 5000
user-agent: "MyCrawler/1.0"
spring:
datasource:
url: jdbc:h2:mem:testdb
driver-class-name: org.h2.Driver
jpa:
hibernate:
ddl-auto: update
show-sql: false # 开发可以开true,生产务必关!
然后在Service里用 @Value 注入:
@Value("${app.crawler.timeout}")
private int timeout;
@Value("${app.crawler.user-agent}")
private String userAgent;
2. 异常处理要优雅
现在如果URL无效,会返回500错误。加个全局异常处理器:
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(RuntimeException.class)
public ResponseEntity<Map<String, String>> handleRuntime(RuntimeException ex) {
Map<String, String> error = Map.of("error", ex.getMessage());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(error);
}
}
这样,非法请求会返回400 + 友好提示,而不是堆栈信息(线上千万别暴露堆栈!)。
3. 打包部署
在项目根目录执行:
./mvnw clean package
生成 target/springboot-crawler-demo-0.0.1-SNAPSHOT.jar
运行:
java -jar target/*.jar
搞定!这个jar自带Tomcat,不需要额外装Web服务器。这才是Spring Boot的精髓:开箱即用。
我们之前上线新服务,运维老王再也不用求爷爷告奶奶配Nginx了,直接丢jar包,systemd托管,日志用logback按天切割——香得很。
性能与扩展:别只顾跑通
虽然这是入门教程,但作为前技术总监,我得提两句架构上的事:
- 爬虫别阻塞主线程:现在的实现是同步的,高并发下会卡死。生产环境要用
@Async或消息队列(比如RabbitMQ)解耦。 - 限流防刷:加个Redis计数器,防止被人当免费代理用。
- 连接池:Jsoup默认没有连接池,高频请求建议用OkHttp + 连接池管理。
- 监控:加上Actuator,暴露
/actuator/health,方便K8s探活。
不过这些,等你60分钟上手之后再考虑吧。先跑起来,再优化。
为什么我要写这篇教程?
说实话,我见过太多人学Spring Boot,卡在“环境配不通”、“依赖冲突”、“启动报错看不懂”上,最后放弃。而实际上,Spring Boot的设计哲学就是“约定优于配置” ——你只要按它的套路走,大部分事情它都帮你搞定了。
我离职前最后一周,帮一个想转Java的前端同事搭环境。他之前用Go写过爬虫(Go确实快,goroutine天生适合IO密集型任务),但公司要求用Java。我花了20分钟带他跑通上面这个demo,他眼睛一亮:“原来Java也能这么轻量?”
所以,别被“企业级”、“微服务”、“分布式事务”吓到。Spring Boot的起点,就是一个main方法 + 一个Controller。
最后:关于简历和Go
我知道很多人学Spring Boot是为了丰富简历。那我建议:别只写“熟悉Spring Boot”,而是写“使用Spring Boot开发了XX爬虫服务,支持日均10万次请求,QPS 200+”。
至于Go?我自己的创业项目后端主力语言就是Go——简洁、高效、部署方便。但技术选型要看场景。如果你团队全是Java栈,硬上Go反而增加维护成本。
Spring Boot依然是国内Java后端的事实标准。掌握它,不是为了卷,而是为了拥有选择权。
好了,60分钟到了吗?希望你已经跑起了自己的第一个Spring Boot服务。
代码我放GitHub了(搜 k-chengdu/springboot-crawler-demo),欢迎star(虽然我现在不靠这个找工作了 😄)。
下次见。我得去改我的BP了——创业狗的日子,也不比996轻松多少啊。
成都的太阳出来了,该去人民公园喝杯盖碗茶了。代码可以等,生活不能。

评论 0