7-[SpringBoot 启航] 快速入门与核心原理

7-[SpringBoot 启航] 快速入门与核心原理
Prorise1. [SpringBoot 启航] 快速入门与核心原理
摘要: 本章将引导您迈出 Spring Boot 开发的第一步。我们将使用官方脚手架快速搭建并运行一个 Web 服务,理解其便捷部署的原理,并深入剖析 Spring Boot 两大核心特性——启动器 (Starter) 与 自动配置 (Auto-configuration)。
1.1. Spring Boot 快速部署
在开始动手之前,我们先花一分钟了解现代 Web 应用的主流架构模式,这将帮助我们理解为何 Spring Boot 的设计如此契合当下的开发需求。
1.1.1. 现代 Web 架构:前后端分离简介
现代 Web 开发大多采用 前后端分离 的模式。在这种架构下,前端(通常由 Vue, React, Angular 等框架构建)和后端(我们的 Spring Boot 应用)是两个独立的项目。
- 后端 (Backend): 不再负责渲染 HTML 页面。它的核心职责是提供一套 API 接口(通常是 RESTful API),处理业务逻辑,操作数据库,并以统一的数据格式(如 JSON)返回结果。
- 前端 (Frontend): 负责用户界面的展示和交互。它通过调用后端的 API 接口获取数据,然后将数据动态地渲染到页面上。
这种模式带来了职责清晰、开发高效、技术栈灵活等诸多好处。我们的教程将完全基于这种前后端分离的模式进行。
1.1.2. [实践] 使用 Spring Initializr 创建第一个 Web 应用
现在,我们来实现第一个需求:创建一个 Web 服务,当用户访问 http://localhost:8080/hello
时,页面显示 “Hello, Spring Boot!”。
创建 Spring Boot 项目最快、最标准的方式是使用官方的 Spring Initializr (俗称“脚手架”)。
1. 使用 Idea 生成项目
- 配置选项:
- Project: Maven
- Language: Java
- Spring Boot: 3.3.3 (或更高稳定版)
- Project Metadata:
- Group:
com.example
- Artifact:
spring-boot-demo
- Packaging: Jar
- Java: 17 (Spring Boot 3.x 要求 JDK 17+)
- Group:
- Dependencies: 点击 “ADD DEPENDENCIES…”,搜索并添加
Spring Web
。
配置完成后,点击 “GENERATE” 按钮,下载项目压缩包并用 IDEA 打开。
2. 剖析项目结构与 pom.xml
IDEA 加载完成后,您会看到一个标准的 Maven 项目结构。
1 | . 📂 spring-boot-demo |
我们重点关注 pom.xml
中的两个核心配置:
文件路径: spring-boot-demo/pom.xml
1 |
|
1.1.3. [实践] 编写 @RestController
并运行服务
1. 编写 Controller
文件路径: src/main/java/com/example/springbootdemo/controller/HelloController.java
(新增文件)
1 | package com.example.springbootdemo.controller; |
重要: 我们自己创建的类(如 Controller, Service)必须放在 启动类 SpringBootDemoApplication.java
所在的包或其子包 下,才能被 Spring Boot 默认的组件扫描机制发现。
2. 运行与验证
现在,找到 SpringBootDemoApplication.java
,直接右键运行其 main
方法。
1 | // SpringBootDemoApplication.java |
当控制台输出 Tomcat started on port(s): 8080 (http)
时,表示服务已成功启动。
打开浏览器,访问 http://localhost: 8080/hello。
1.2. 便捷的部署与执行
Spring Boot 极大地简化了应用的部署过程,其核心就是 可执行 JAR 包。
1.2.1. [实践] 打包为可执行 Fat JAR
在 IDEA 的 Maven 窗口中,执行 package
命令。
打包成功后,在 target
目录下会生成一个 spring-boot-demo-0.0.1-SNAPSHOT.jar
文件。将这个 JAR 包复制到 任何安装了 Java 17+ 环境 的机器上,在命令行中执行:
1 | java -jar spring-boot-demo-0.0.1-SNAPSHOT.jar |
1
2
3
4
5
6
7
8
9
10
11
12
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.3.3)
... (省略日志)
...
2025-08-14T21:30:00.123Z INFO 12345 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
...
服务再次启动!这证明了 Spring Boot 应用的 可移植性,无需外部的 Tomcat 服务器。
1.2.2. Spring Boot JAR 与普通 JAR 的区别
为什么 Spring Boot 的 JAR 包可以直接运行,而普通的 JAR 包不行?
Spring Boot 打包的“Fat JAR”和我们平时用的普通 JAR,在结构上有什么本质区别?
最大的区别在于内容。普通 JAR 只包含我们自己编写的 .class
文件和资源。而 Spring Boot 的 Fat JAR 除了包含我们自己的代码,还内置了三样关键东西:
1.所有运行时依赖 : 所有的第三方 JAR 包(如 Spring MVC, Tomcat, Jackson)都被打包进来了。
2.内嵌的 : Tomcat 服务器的 JAR 包也被包含在内。
3.一个特殊的启动器类 :Spring Boot 提供了一个 JarLauncher
类,它知道如何正确地加载所有内嵌的依赖并启动应用。
非常好。所以,可执行性就是这么来的?
是的。Fat JAR 的 MANIFEST.MF
文件中,Main-Class
被指向了这个 JarLauncher
。所以当我们执行 java -jar
时,实际上是 JarLauncher
在工作,它创建了一个特殊的类加载器来加载 BOOT-INF/lib/
下的依赖,然后才调用我们自己写的 main
方法。而普通 JAR 没有这个机制。
1.3. 自动配置核心揭秘
我们已经体验到了 Spring Boot 的便捷,现在是时候揭开其背后的魔法了。
1.3.1. [面试题] SpringApplication.run()
背后发生了什么?
当我们执行 SpringApplication.run(MyApplication.class, args)
这一行代码时,Spring Boot 在背后都做了哪些核心工作?
这是一个经典的启动流程问题。概括来说,它主要做了四件大事:
1.推断应用类型 : Spring Boot 会检查类路径,判断这是一个标准的 Servlet Web 应用,还是一个响应式的 WebFlux 应用,或是一个非 Web 应用。
2.加载自动配置类 : 这是最核心的一步。它会从所有依赖的 JAR 包中,找到 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
文件,加载里面定义的所有自动配置类。
3.创建并准备IoC容器 : 创建一个 ApplicationContext
实例,然后执行一系列的准备工作,比如加载我们的主配置类 (MyApplication.class
),将命令行参数 args
注册为 Bean 等。
4.刷新容器并启动组件 : “刷新” 容器是 Spring 的一个术语,它会触发所有 Bean 的实例化、依赖注入、初始化等过程。在这个过程中,之前加载的自动配置类会根据条件 (@ConditionalOn...
) 判断是否生效。对于 Web 应用,此阶段还会启动内嵌的 Tomcat 服务器。
1.3.2. 魔法的起点:@SpringBootApplication
注解剖析
我们可以在 SpringBootDemoApplication
里面找到这个注解,那么这个注解的作用是什么?
SpringApplication.run()
的所有行为,都源于启动类上的 @SpringBootApplication
注解。它是一个复合注解,由三个核心注解组成:
@SpringBootConfiguration
:- 它本身被
@Configuration
注解,所以 Spring Boot 的主启动类本质上就是一个 Java 配置类。这意味着我们可以在启动类中直接定义@Bean
。
- 它本身被
@EnableAutoConfiguration
:- 启用自动配置。这是 Spring Boot 最神奇的地方。它会触发上面提到的“加载自动配置类”的流程。
@ComponentScan
:- 启用组件扫描。它告诉 Spring 去哪里查找我们自己定义的 Bean(如
@Component
,@Service
,@RestController
等)。默认的扫描路径是 启动类所在的包及其所有子包。
- 启用组件扫描。它告诉 Spring 去哪里查找我们自己定义的 Bean(如
1.3.3. 按需加载:条件注解 (@ConditionalOn...
) 的作用
@EnableAutoConfiguration
虽然加载了所有可能的自动配置类,但并非所有都会生效。每个自动配置类都被一系列的 条件注解 (@ConditionalOn...
) 所保护。
工作原理:
Spring Boot 在处理自动配置类时,会检查其上的条件注解。只有当所有条件都满足时,这个配置类才会生效
常用条件注解:
注解 | 作用 |
---|---|
@ConditionalOnClass | 当类路径下 存在 指定的类时,配置生效。 (这是最常用的) |
@ConditionalOnMissingClass | 当类路径下 不存在 指定的类时,配置生效。 |
@ConditionalOnBean | 当 IoC 容器中 存在 指定的 Bean 时,配置生效。 |
@ConditionalOnMissingBean | 当 IoC 容器中 不存在 指定的 Bean 时,配置生效。 (常用于提供默认 Bean) |
@ConditionalOnProperty | 当 application.properties 中 存在 指定的配置项时,配置生效。 |
@ConditionalOnWebApplication | 仅当当前应用是 Web 应用 时,配置生效。 |
示例:WebMvcAutoConfiguration
(Spring MVC 的自动配置) 的部分源码:
1 | // 只有当应用是 Servlet Web 应用,并且类路径下存在 Servlet, DispatcherServlet, WebMvcConfigurer 时, |