Spring Boot 学习:原理、注解、配置文件与部署解析
一、Spring Boot 核心定位与价值
Spring Boot 是由 Pivotal 团队(后归属于 VMware)基于 Spring Framework 开发的轻量级、约定大于配置的快速开发框架,核心目标是:
消除 Spring 框架繁琐的 XML / 注解配置,降低入门门槛;
简化依赖管理,解决 "依赖地狱" 问题;
提供一站式的企业级应用开发能力,快速构建独立、可运行的应用;
无缝集成 Spring 生态(Spring MVC、Spring Data、Spring Security 等)。
核心价值:让开发者从 "配置繁琐" 中解放,聚焦业务逻辑开发,实现 "开箱即用、快速迭代"。
二、Spring Boot 核心架构与核心组件
1. 核心架构(极简版)

2. 核心组件详解
(1)核心注解:@SpringBootApplication
这是 Spring Boot 最核心的注解,是一个 "组合注解",包含 3 个关键注解:
java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
// 1. 核心:开启自动配置
@EnableAutoConfiguration
// 2. 扫描当前包及子包下的@Component/@Controller/@Service等注解
@ComponentScan
// 3. 标记当前类为配置类,可定义@Bean
@Configuration
public @interface SpringBootApplication {
// 排除特定自动配置类
Class<?>[] exclude() default {};
}
@EnableAutoConfiguration:触发自动配置核心逻辑,是 Spring Boot "约定大于配置" 的核心;
@ComponentScan :替代传统 Spring 的 <context:component-scan>,自动扫描组件;
@Configuration :替代传统 Spring 的 XML 配置文件,支持通过 @Bean 定义组件。
(2)自动配置(AutoConfiguration)
Spring Boot 最核心的特性,底层基于Spring 条件注解(@Conditional) 实现:
原理 :启动时,Spring Boot 会扫描 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件,加载所有自动配置类(如 WebMvcAutoConfiguration、DataSourceAutoConfiguration);
逻辑 :每个自动配置类通过 @ConditionalOnClass(类存在时生效)、@ConditionalOnMissingBean(Bean 不存在时生效)等注解,判断是否需要自动配置组件;
示例 :引入 spring-boot-starter-web 依赖后,WebMvcAutoConfiguration 会自动配置 DispatcherServlet、视图解析器、JSON 转换器等,无需手动配置。
(3)起步依赖(Starter Dependencies)
Spring Boot 将常用的依赖组合打包成 "启动器",解决依赖版本冲突、手动引入漏项问题:
核心设计:每个 Starter 都有一个 pom.xml,包含该场景下所有必需的依赖,且版本由 Spring Boot 父工程(spring-boot-starter-parent)统一管理;
常用 Starter:
| Starter 名称 | 用途 | 核心依赖 |
|---|---|---|
| spring-boot-starter-web | Web 开发(RESTful API) | Spring MVC、Tomcat、Jackson |
| spring-boot-starter-data-jpa | 数据库操作(JPA/ORM) | Hibernate、Spring Data JPA |
| spring-boot-starter-data-redis | Redis 操作 | Lettuce/Jedis、Spring Data Redis |
| spring-boot-starter-security | 安全认证(权限 / 登录) | Spring Security |
| spring-boot-starter-test | 单元测试 | JUnit、Mockito、AssertJ |
| spring-boot-starter-actuator | 应用监控 | Actuator 核心组件 |
(4)内嵌服务器
Spring Boot 内置 Tomcat(默认)、Jetty、Undertow 等 Web 服务器,无需外部部署:
原理:通过 spring-boot-starter-web 引入 tomcat-embed-core 等依赖,启动时通过 SpringApplication 自动启动内嵌服务器;
切换服务器:排除 Tomcat 依赖,引入 Jetty/Undertow 即可:
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 引入 Jetty -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
(5)配置管理体系
Spring Boot 支持多维度配置,优先级从高到低:
- 命令行参数(
--server.port=8081); - 操作系统环境变量;
- 应用外部配置文件(如
./config/application.yml); - 应用内部配置文件(
src/main/resources/application.yml); - 自动配置默认值。
支持的配置格式:properties、yaml、json(推荐 yaml,支持复杂结构)。
三、Spring Boot 工程结构(最佳实践)
规范的工程结构能提升可维护性,以下是企业级项目的标准结构:
plaintext
com.example.demo/
├── DemoApplication.java # 启动类(必须放在根包下)
├── config/ # 自定义配置类
│ ├── MyBatisConfig.java # MyBatis 配置
│ └── SecurityConfig.java # 安全配置
├── controller/ # 控制器(API 入口)
│ ├── UserController.java
│ └── OrderController.java
├── service/ # 业务逻辑层
│ ├── impl/ # 实现类
│ │ ├── UserServiceImpl.java
│ │ └── OrderServiceImpl.java
│ ├── UserService.java # 接口
│ └── OrderService.java
├── mapper/ # 数据访问层(MyBatis/Mapper)
│ ├── UserMapper.java
│ └── OrderMapper.java
├── repository/ # 数据访问层(JPA/Repository)
│ ├── UserRepository.java
│ └── OrderRepository.java
├── entity/ # 实体类(POJO/DO/DTO/VO)
│ ├── User.java
│ └── Order.java
├── exception/ # 自定义异常
│ ├── BusinessException.java
│ └── GlobalExceptionHandler.java # 全局异常处理
├── util/ # 工具类
│ ├── DateUtil.java
│ └── HttpUtil.java
└── resources/ # 资源目录
├── application.yml # 主配置文件
├── application-dev.yml # 开发环境配置
├── application-prod.yml # 生产环境配置
├── mapper/ # MyBatis 映射文件
│ ├── UserMapper.xml
│ └── OrderMapper.xml
├── static/ # 静态资源(CSS/JS/图片)
└── templates/ # 模板文件(Thymeleaf/Freemarker)
工程分层架构图

四、Spring Boot 核心开发流程
以开发一个 "用户管理" RESTful API 为例,完整流程如下:
1. 环境准备
JDK 11/17(推荐 LTS 版本);
Maven/Gradle(构建工具);
IDE(IntelliJ IDEA);
Spring Boot 3.2.x(稳定版)。
2. 创建项目(Spring Initializr)
选择:Maven → Java → Spring Boot 3.2.x;
Group:com.example,Artifact:user-demo;
勾选依赖:Spring Web、Spring Data JPA、MySQL Driver;
下载项目,解压后用 IDE 打开。
3. 核心开发步骤
步骤 1:配置数据库(application-dev.yml)
yaml
spring:
profiles: dev
datasource:
url: jdbc:mysql://localhost:3306/user_db?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
ddl-auto: update # 自动创建/更新表结构
show-sql: true # 打印SQL语句
properties:
hibernate:
format_sql: true # 格式化SQL
server:
port: 8080
步骤 2:创建实体类(User.java)
java
package com.example.userdemo.entity;
import jakarta.persistence.*;
import lombok.Data;
@Data // Lombok 注解,自动生成getter/setter
@Entity // JPA 实体注解
@Table(name = "t_user") // 对应数据库表名
public class User {
@Id // 主键
@GeneratedValue(strategy = GenerationType.IDENTITY) // 自增
private Long id;
@Column(name = "username", unique = true, nullable = false) // 列属性
private String username;
@Column(name = "password", nullable = false)
private String password;
@Column(name = "email")
private String email;
}
步骤 3:创建 Repository(数据访问层)
java
package com.example.userdemo.repository;
import com.example.userdemo.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
// JpaRepository<实体类, 主键类型> 提供CRUD、分页等默认方法
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
// 自定义查询:根据用户名查询用户
User findByUsername(String username);
}
步骤 4:创建 Service(业务逻辑层)
java
// 接口
package com.example.userdemo.service;
import com.example.userdemo.entity.User;
import java.util.List;
public interface UserService {
User saveUser(User user);
User getUserById(Long id);
User getUserByUsername(String username);
List<User> getAllUsers();
void deleteUser(Long id);
}
// 实现类
package com.example.userdemo.service.impl;
import com.example.userdemo.entity.User;
import com.example.userdemo.repository.UserRepository;
import com.example.userdemo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
@Override
public User saveUser(User user) {
return userRepository.save(user);
}
@Override
public User getUserById(Long id) {
// orElseThrow:不存在则抛异常
return userRepository.findById(id)
.orElseThrow(() -> new RuntimeException("用户不存在"));
}
@Override
public User getUserByUsername(String username) {
return userRepository.findByUsername(username);
}
@Override
public List<User> getAllUsers() {
return userRepository.findAll();
}
@Override
public void deleteUser(Long id) {
userRepository.deleteById(id);
}
}
步骤 5:创建 Controller(API 层)
java
package com.example.userdemo.controller;
import com.example.userdemo.entity.User;
import com.example.userdemo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController // @Controller + @ResponseBody
@RequestMapping("/api/users") // 统一前缀
public class UserController {
@Autowired
private UserService userService;
// 新增用户:POST请求
@PostMapping
public User createUser(@RequestBody User user) {
return userService.saveUser(user);
}
// 根据ID查询用户:GET请求
@GetMapping("/{id}")
public User getUserById(@PathVariable Long id) {
return userService.getUserById(id);
}
// 查询所有用户:GET请求
@GetMapping
public List<User> getAllUsers() {
return userService.getAllUsers();
}
// 删除用户:DELETE请求
@DeleteMapping("/{id}")
public String deleteUser(@PathVariable Long id) {
userService.deleteUser(id);
return "删除成功";
}
}
步骤 6:启动应用并测试
运行 UserDemoApplication 的 main 方法;
使用 Postman / 浏览器测试 API:
新增用户:POST http://localhost:8080/api/users,请求体(JSON):
json
{
"username": "zhangsan",
"password": "123456",
"email": "zhangsan@example.com"
}
查询所有用户:GET http://localhost:8080/api/users;
查询单个用户:GET http://localhost:8080/api/users/1。
五、Spring Boot 高级特性
1. 多环境配置
方式 1:拆分文件(推荐):
application-dev.yml(开发)、application-test.yml(测试)、application-prod.yml(生产);
激活环境:spring.profiles.active=prod(可通过命令行覆盖:java -jar user-demo.jar --spring.profiles.active=prod)。
方式 2:单文件多环境:用 --- 分隔,适合简单场景。
2. 全局异常处理
通过 @RestControllerAdvice + @ExceptionHandler 统一处理异常:
java
package com.example.userdemo.exception;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
// 全局异常处理,作用于所有@RestController
@RestControllerAdvice
public class GlobalExceptionHandler {
// 处理自定义业务异常
@ExceptionHandler(BusinessException.class)
public ResponseEntity<String> handleBusinessException(BusinessException e) {
return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
}
// 处理通用异常
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleException(Exception e) {
return new ResponseEntity<>("服务器内部错误:" + e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
3. 应用监控(Actuator)
引入依赖:
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
配置暴露端点:
yaml
management:
endpoints:
web:
exposure:
include: health,info,metrics,beans # 暴露的端点
endpoint:
health:
show-details: always # 显示健康详情
访问监控端点:
健康状态:http://localhost:8080/actuator/health;
应用信息:http://localhost:8080/actuator/info;
Bean 列表:http://localhost:8080/actuator/beans。
4. 打包与部署
打包为可执行 JAR:
bash
mvn clean package # 打包后生成 target/user-demo-0.0.1-SNAPSHOT.jar
运行 JAR 包:
bash
java -jar user-demo-0.0.1-SNAPSHOT.jar # 直接运行
# 带参数运行(覆盖配置)
java -jar user-demo-0.0.1-SNAPSHOT.jar --server.port=8081 --spring.profiles.active=prod
生产环境部署:可结合 Docker、K8s 实现容器化部署。
六、Spring Boot 与微服务
Spring Boot 是微服务架构的基础,结合 Spring Cloud 可构建完整的微服务体系:
Spring Boot:负责单个微服务的快速开发、独立部署;
Spring Cloud:基于 Spring Boot 提供微服务治理能力(服务注册发现、配置中心、熔断降级、网关等);
核心组件:Spring Cloud Netflix(Eureka、Ribbon、Hystrix)、Spring Cloud Alibaba(Nacos、Sentinel)、Spring Cloud Gateway 等。
七、Spring 与Spring Boot的区别
| 维度 | Spring 框架 | Spring Boot |
|---|---|---|
| 定位 | 一站式企业级 Java 开发框架(核心是 IoC/DI、AOP) | Spring 框架的快速开发脚手架(简化配置、快速启动) |
| 配置方式 | 大量手动配置(XML 为主,后期支持注解) | 自动配置(Auto-configuration)+ 少量手动配置 |
| 依赖管理 | 手动引入所有依赖,需手动解决版本冲突 | 起步依赖(Starter),一键引入相关依赖,自动管理版本 |
| 内嵌服务器 | 无,需手动部署到 Tomcat/Jetty 等 | 内置 Tomcat/Jetty/Undertow,直接运行 JAR 包 |
| 启动方式 | 需部署到外部服务器,或编写复杂启动类 | 直接运行 main 方法,或 java -jar 启动 |
| 开发效率 | 低(配置繁琐、依赖易冲突) | 高(零配置 / 少配置,快速搭建项目) |
| 适用场景 | 复杂定制化项目(需深度控制配置) | 快速开发微服务、RESTful API、中小型应用 |
八、配置文件
Spring Boot 默认支持 application.properties/application.yml,是项目内的静态配置(如数据库地址、端口)
Spring Boot 默认加载 src/main/resources 下的 application.properties 或 application.yml,推荐用 application.yml(语法更简洁)。
示例配置文件(application.yml):
yaml
# 自定义普通配置
app:
name: "我的SpringBoot应用"
version: "1.0.0"
author: "张三"
# 嵌套配置
database:
mysql:
url: "jdbc:mysql://localhost:3306/test"
username: "root"
password: "123456"
# 数组/列表配置
servers:
- "192.168.1.100"
- "192.168.1.101"
- "192.168.1.102"
读取配置的 3 种常用方法
方法 1:@Value 注解(简单配置,直接读取)
适合读取单个、简单的配置项,直接注入到变量中。
java
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ConfigController {
// 读取普通字符串配置
@Value("${app.name}")
private String appName;
@Value("${app.version}")
private String appVersion;
// 读取嵌套配置
@Value("${database.mysql.url}")
private String mysqlUrl;
// 读取列表配置(需用#{}解析)
@Value("${servers}")
private List<String> serverList;
// 配置不存在时设置默认值(避免报错)
@Value("${app.port:8080}") // 若app.port未配置,默认值8080
private Integer appPort;
@GetMapping("/config/value")
public String getConfigByValue() {
return String.format(
"应用名称:%s,版本:%s,MySQL地址:%s,默认端口:%d,服务器列表:%s",
appName, appVersion, mysqlUrl, appPort, serverList.toString()
);
}
}
方法 2:@ConfigurationProperties 注解(批量绑定,推荐复杂配置)
适合读取一组相关的配置(如数据库配置、自定义应用配置),批量绑定到一个实体类,更优雅、易维护。
步骤 1:创建配置实体类
java
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
// 声明这是配置属性类,prefix指定配置前缀
@ConfigurationProperties(prefix = "app")
// 注册为Spring组件,才能被注入使用
@Component
public class AppConfig {
// 字段名需与配置文件中的key一致(如app.name → name)
private String name;
private String version;
private String author;
// 嵌套配置(对应database.mysql)
private DatabaseConfig database;
// 列表配置
private List<String> servers;
// 静态内部类:绑定嵌套的database.mysql配置
public static class DatabaseConfig {
private String url;
private String username;
private String password;
// 生成getter/setter(必须!否则无法绑定)
public String getUrl() { return url; }
public void setUrl(String url) { this.url = url; }
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
}
// 生成所有字段的getter/setter(IDEA可快捷键:Alt+Insert → Getter and Setter)
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getVersion() { return version; }
public void setVersion(String version) { this.version = version; }
public String getAuthor() { return author; }
public void setAuthor(String author) { this.author = author; }
public DatabaseConfig getDatabase() { return database; }
public void setDatabase(DatabaseConfig database) { this.database = database; }
public List<String> getServers() { return servers; }
public void setServers(List<String> servers) { this.servers = servers; }
}
步骤 2:注入并使用配置类
java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ConfigController2 {
// 注入配置实体类
@Autowired
private AppConfig appConfig;
@GetMapping("/config/batch")
public String getConfigByBatch() {
return String.format(
"应用信息:%s(v%s),作者:%s;MySQL地址:%s,用户名:%s;服务器列表:%s",
appConfig.getName(),
appConfig.getVersion(),
appConfig.getAuthor(),
appConfig.getDatabase().getUrl(),
appConfig.getDatabase().getUsername(),
appConfig.getServers().toString()
);
}
}
方法 3:注入 Environment 接口(通用方式)
Environment 是 Spring 核心接口,可读取所有配置(包括配置文件、环境变量、命令行参数),适合动态读取配置。
java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ConfigController3 {
// 注入Environment
@Autowired
private Environment env;
@GetMapping("/config/env")
public String getConfigByEnv() {
// 通过key读取配置
String appName = env.getProperty("app.name");
String mysqlPwd = env.getProperty("database.mysql.password");
// 读取时指定默认值
String appDesc = env.getProperty("app.desc", "这是一个默认描述");
return String.format(
"应用名称:%s,MySQL密码:%s,应用描述:%s",
appName, mysqlPwd, appDesc
);
}
}
Spring Boot 读取配置的优先级从高到低:
- 命令行参数(
--key=value) - 操作系统环境变量
application.yml/application.properties(项目内)- 内置默认配置
properties 与 YAML 对比表
| 维度 | properties 格式 | YAML 格式 |
|---|---|---|
| 语法结构 | 键值对格式:key=value,层级用 . 分隔 |
层级缩进格式:key: value,依赖空格缩进(不能用 Tab) |
| 数据类型支持 | 仅支持字符串(需手动转换类型) | 原生支持字符串、数字、布尔、列表、对象等 |
| 层级表达 | 重复前缀(如 database.mysql.url) |
缩进嵌套,无重复前缀,更简洁 |
| 列表 / 数组支持 | 需特殊格式(如 servers[0]=192.168.1.1) |
原生支持 - 符号定义列表,直观易懂 |
| 注释 | 仅支持单行注释(#) |
仅支持单行注释(#) |
| 多环境配置 | 需拆分文件(如 application-dev.properties) |
可单文件通过 --- 分隔多环境,也可拆分文件 |
| 兼容性 | 所有 Java 框架都支持,无兼容问题 | 需依赖 SnakeYAML 库(Spring Boot 已内置),低版本框架可能不支持 |
| 可读性 | 简单配置清晰,复杂配置冗余 | 复杂配置结构清晰,简洁易读 |
语法差异:
properties:键值对 + 点分隔层级
语法是 层级1.层级2.键=值,所有值默认是字符串,即使写数字 / 布尔,读取时也需手动转换。
properties
# application.properties 示例
# 基础键值对
app.name=我的SpringBoot应用
app.version=1.0.0
app.enabled=true # 本质是字符串"true",不是布尔值
# 层级嵌套(重复前缀)
database.mysql.url=jdbc:mysql://localhost:3306/test
database.mysql.username=root
database.mysql.password=123456
# 列表/数组(语法繁琐)
servers[0]=192.168.1.100
servers[1]=192.168.1.101
servers[2]=192.168.1.102
YAML:缩进 + 冒号分隔,支持复杂结构
语法是 层级1: 换行 + 缩进 + 层级2: 值,必须用空格缩进(2 个空格最佳,不能用 Tab),原生支持多数据类型和嵌套结构。
yaml
# application.yml 示例
# 基础键值对(注意冒号后有空格)
app:
name: 我的SpringBoot应用
version: 1.0.0 # 数字类型
enabled: true # 布尔类型(原生支持)
# 层级嵌套(无重复前缀,缩进体现层级)
database:
mysql:
url: jdbc:mysql://localhost:3306/test
username: root
password: 123456
# 列表/数组(- 符号定义,直观)
servers:
- 192.168.1.100
- 192.168.1.101
- 192.168.1.102
# 更复杂的对象列表(YAML 优势)
users:
- name: 张三
age: 25
enabled: true
- name: 李四
age: 30
enabled: false
数据类型支持差异:
properties :所有配置值都是字符串,比如你写 app.port=8080,读取到的是字符串 "8080",若要转成整数,需手动处理:
java
@Value("${app.port}")
private String portStr; // 读出来是字符串
// 手动转整数
int port = Integer.parseInt(portStr);
YAML:原生支持多类型,Spring Boot 会自动转换类型:
java
@Value("${app.port}")
private int port; // 直接读成整数,无需转换
@Value("${app.enabled}")
private boolean enabled; // 直接读成布尔值
多环境配置差异:
Spring Boot 支持多环境(开发 / 测试 / 生产)配置,两者实现方式不同:
properties 实现多环境
需拆分多个文件,比如:
application-dev.properties(开发环境)
application-test.properties(测试环境)
application-prod.properties(生产环境)
然后在主配置文件 application.properties 中指定激活的环境:
properties
spring.profiles.active=dev # 激活开发环境
YAML 实现多环境
两种方式:
方式 1:拆分文件(和 properties 一样,如 application-dev.yml);
方式 2:单文件分隔(更简洁,用 --- 分隔不同环境):
yaml
# 全局配置(所有环境共用)
server:
port: 8080
# 开发环境(dev)
---
spring:
profiles: dev
database:
mysql:
url: jdbc:mysql://localhost:3306/dev_db
# 生产环境(prod)
---
spring:
profiles: prod
database:
mysql:
url: jdbc:mysql://prod-server:3306/prod_db
激活环境:spring.profiles.active=prod
九、常用注解
1.@SpringBootApplication
作用:Spring Boot 项目的启动核心注解,是组合注解(包含 @Configuration、@EnableAutoConfiguration、@ComponentScan),放在项目启动类上,触发自动配置、组件扫描等核心逻辑。
示例:
java
// 项目入口类,放在根包下
@SpringBootApplication
// 可选:排除不需要的自动配置类
// @SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class DemoApplication {
public static void main(String[] args) {
// 启动 Spring Boot 应用
SpringApplication.run(DemoApplication.class, args);
}
}
2. @Configuration
作用:标记类为配置类,替代传统 Spring 的 XML 配置文件,可在类中通过 @Bean 注解手动注册组件到 Spring 容器。
示例:
java
// 自定义配置类
@Configuration
public class MyAppConfig {
// 注册 RestTemplate 组件,供其他类注入使用
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
// 注册 RedisTemplate 组件(示例)
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
return template;
}
}
3. @ComponentScan
作用:指定 Spring 扫描组件的包路径,默认扫描当前注解所在类的包及子包;若启动类和业务类不在同一包层级,需手动指定扫描路径。
示例:
java
// 手动指定扫描多个包
@SpringBootApplication
@ComponentScan(basePackages = {"com.example.controller", "com.example.service"})
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
4. @EnableAutoConfiguration
作用:开启 Spring Boot 自动配置核心逻辑,已包含在 @SpringBootApplication 中,一般不单独使用;底层通过扫描自动配置类,根据依赖和条件自动初始化组件。
示例:
java
// 极少单独使用,通常结合 @Configuration 使用
@Configuration
@EnableAutoConfiguration
public class CustomAutoConfig {}
组件注册注解
用于将类标记为 Spring 容器管理的 Bean,实现依赖注入,是分层开发的核心注解。
1. @Component
作用:通用组件注解,标记任意类为 Spring Bean,是 @Controller、@Service、@Repository 的父注解,适用于无法归类到具体分层的通用工具类。
示例:
java
// 通用工具类,注册为 Spring Bean
@Component
public class DateUtil {
public String formatDate(Date date) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
return sdf.format(date);
}
}
2. @Controller
作用:标记类为 MVC 控制器,主要用于返回视图 / 页面(如 Thymeleaf 模板),配合 @RequestMapping 处理前端页面请求。
示例:
java
// 页面控制器,返回 HTML 页面
@Controller
@RequestMapping("/pages")
public class PageController {
// 访问 /pages/index 时,返回 templates/index.html 页面
@GetMapping("/index")
public String index(Model model) {
model.addAttribute("title", "首页");
return "index"; // 对应 resources/templates/index.html
}
}
3. @RestController
作用:组合注解(@Controller + @ResponseBody),专门用于开发 RESTful API,返回 JSON / 字符串数据,而非页面,是后端接口开发的核心注解。
示例:
java
// API 控制器,返回 JSON 数据
@RestController
@RequestMapping("/api/users")
public class UserApiController {
// 访问 /api/users 时,返回用户列表 JSON
@GetMapping
public List<User> listUsers() {
List<User> users = new ArrayList<>();
users.add(new User(1L, "zhangsan", "123456"));
return users;
}
}
4. @Service
作用:标记类为业务逻辑层组件,明确标注业务层代码,便于代码分层管理和 Spring 容器识别。
示例:
java
// 业务逻辑层,处理用户相关业务
@Service
public class UserService {
public User getUserById(Long id) {
// 模拟从数据库查询用户
return new User(id, "zhangsan", "123456");
}
public void saveUser(User user) {
// 模拟保存用户逻辑
System.out.println("保存用户:" + user.getUsername());
}
}
5. @Repository
作用:标记类为数据访问层(DAO/Mapper)组件,专门用于数据库操作,Spring 会自动处理数据访问相关的异常转换。
示例:
java
// 数据访问层,操作用户表
@Repository
public class UserMapper {
// 模拟从数据库查询用户
public User selectById(Long id) {
return new User(id, "zhangsan", "123456");
}
}
6. @Autowired
作用:自动注入 Spring 容器中的 Bean(按类型注入),无需手动创建对象,是依赖注入的核心注解;可用于字段、构造方法、setter 方法。
示例:
java
@RestController
@RequestMapping("/api/users")
public class UserApiController {
// 字段注入:自动注入 UserService Bean
@Autowired
private UserService userService;
// 构造方法注入(推荐,更符合依赖注入规范)
// private final UserService userService;
// @Autowired
// public UserApiController(UserService userService) {
// this.userService = userService;
// }
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
// 使用注入的 UserService 调用业务方法
return userService.getUserById(id);
}
}
7. @Resource
作用:JDK 原生注解,与 @Autowired 类似,用于依赖注入,但默认按名称 注入(而非类型),可通过 name 属性指定注入的 Bean 名称。
示例:
java
@RestController
@RequestMapping("/api/orders")
public class OrderController {
// 按名称注入:注入名称为 "orderService" 的 Bean
@Resource(name = "orderService")
private OrderService orderService;
@GetMapping("/{id}")
public Order getOrder(@PathVariable Long id) {
return orderService.getOrderById(id);
}
}
请求映射注解(高频)
用于映射 HTTP 请求(URL、请求方式),是接口开发的核心注解。
1. @RequestMapping
作用:通用请求映射注解,可映射任意 HTTP 请求方式(GET/POST/PUT/DELETE 等),可用于类(指定基础路径)或方法(指定具体路径)。
示例:
java
@RestController
// 类级别:所有方法的基础路径为 /api/products
@RequestMapping("/api/products")
public class ProductController {
// 方法级别:映射 GET 请求到 /api/products
@RequestMapping(method = RequestMethod.GET)
public List<Product> listProducts() {
List<Product> products = new ArrayList<>();
products.add(new Product(1L, "手机", 2999.0));
return products;
}
// 方法级别:映射 POST 请求到 /api/products
@RequestMapping(method = RequestMethod.POST)
public String addProduct(@RequestBody Product product) {
System.out.println("添加商品:" + product.getName());
return "添加成功";
}
}
2. @GetMapping
作用:简化版 @RequestMapping,专门映射 GET 请求,是查询类接口的常用注解。
示例:
java
@RestController
@RequestMapping("/api/products")
public class ProductController {
// 映射 GET 请求到 /api/products/{id}
@GetMapping("/{id}")
public Product getProduct(@PathVariable Long id) {
return new Product(id, "手机", 2999.0);
}
}
3. @PostMapping
作用:简化版 @RequestMapping,专门映射 POST 请求,用于新增数据的接口。
示例:
java
@RestController
@RequestMapping("/api/products")
public class ProductController {
// 映射 POST 请求到 /api/products
@PostMapping
public String addProduct(@RequestBody Product product) {
System.out.println("新增商品:" + product.getName());
return "新增成功,商品ID:" + product.getId();
}
}
4. @PutMapping
作用:专门映射 PUT 请求,用于更新数据的接口(全量更新)。
示例:
java
@RestController
@RequestMapping("/api/products")
public class ProductController {
// 映射 PUT 请求到 /api/products/{id}
@PutMapping("/{id}")
public String updateProduct(@PathVariable Long id, @RequestBody Product product) {
product.setId(id);
System.out.println("更新商品:" + product);
return "更新成功";
}
}
5. @DeleteMapping
作用:专门映射 DELETE 请求,用于删除数据的接口。
示例:
java
@RestController
@RequestMapping("/api/products")
public class ProductController {
// 映射 DELETE 请求到 /api/products/{id}
@DeleteMapping("/{id}")
public String deleteProduct(@PathVariable Long id) {
System.out.println("删除商品:" + id);
return "删除成功";
}
}
请求参数注解
用于获取前端传递的请求参数,是接口接收参数的核心注解。
1. @PathVariable
作用:获取 URL 路径中的参数(如 /api/products/{id} 中的 id),适用于 RESTful 风格的路径参数。
示例:
java
@RestController
@RequestMapping("/api/products")
public class ProductController {
// 获取路径中的 id 参数
@GetMapping("/{id}")
public Product getProduct(@PathVariable Long id) {
return new Product(id, "手机", 2999.0);
}
// 多个路径参数
@GetMapping("/{id}/category/{cid}")
public Product getProductByCategory(@PathVariable Long id, @PathVariable Long cid) {
return new Product(id, "手机", 2999.0);
}
}
2. @RequestParam
作用:获取 URL 中的查询参数(如 /api/products?name=手机 中的 name),可指定参数名、是否必传、默认值。
示例:
java
@RestController
@RequestMapping("/api/products")
public class ProductController {
// 获取查询参数 name,非必传,默认值为空字符串
@GetMapping("/search")
public List<Product> searchProducts(
@RequestParam(value = "name", required = false, defaultValue = "") String name,
@RequestParam(value = "page", defaultValue = "1") Integer page) {
System.out.println("搜索关键词:" + name + ",页码:" + page);
List<Product> products = new ArrayList<>();
products.add(new Product(1L, name, 2999.0));
return products;
}
}
3. @RequestBody
作用:获取 HTTP 请求体中的 JSON/XML 数据,转换为 Java 对象,适用于 POST/PUT 请求传递复杂参数(如新增 / 更新对象)。
示例:
java
@RestController
@RequestMapping("/api/products")
public class ProductController {
// 获取请求体中的 JSON 数据,转换为 Product 对象
@PostMapping
public String addProduct(@RequestBody Product product) {
System.out.println("商品名称:" + product.getName() + ",价格:" + product.getPrice());
return "新增商品成功";
}
}
4. @RequestHeader
作用:获取 HTTP 请求头中的参数(如 Token、Content-Type 等)。
示例:
java
@RestController
@RequestMapping("/api/users")
public class UserController {
// 获取请求头中的 Token 参数
@GetMapping("/info")
public String getUserInfo(@RequestHeader("Token") String token) {
System.out.println("请求 Token:" + token);
return "用户信息:张三,Token:" + token;
}
}
配置读取注解
用于读取配置文件(application.yml/properties)中的配置项,实现配置与代码解耦。
1. @Value
作用:读取配置文件中的单个配置项,直接注入到字段 / 方法参数中,适用于简单配置。
示例:
java
@Component
public class AppConfig {
// 读取配置文件中的 app.name 配置项
@Value("${app.name}")
private String appName;
// 读取配置项,指定默认值(配置不存在时使用)
@Value("${app.port:8080}")
private Integer appPort;
public void printConfig() {
System.out.println("应用名称:" + appName + ",端口:" + appPort);
}
}
2. @ConfigurationProperties
作用:批量绑定配置文件中的配置项到 Java 对象,适用于复杂的、有层级的配置(如数据库配置、Redis 配置),比 @Value 更优雅。
示例:
java
// 批量绑定配置文件中的 database.mysql 前缀的配置项
@Component
@ConfigurationProperties(prefix = "database.mysql")
public class MysqlConfig {
private String url;
private String username;
private String password;
// 必须提供 getter/setter 方法
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public void printConfig() {
System.out.println("MySQL URL:" + url + ",用户名:" + username);
}
}
事务管理注解
用于控制数据库事务,保证数据操作的原子性。
@Transactional
作用:标记方法 / 类为事务性操作,当方法执行过程中抛出异常时,自动回滚数据库操作;可用于类(所有方法生效)或方法(仅当前方法生效)。
示例:
java
@Service
public class OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private OrderItemMapper orderItemMapper;
// 事务注解:当方法抛出异常时,所有数据库操作回滚
@Transactional(rollbackFor = Exception.class) // 指定所有异常都回滚(默认仅运行时异常)
public void createOrder(Order order, List<OrderItem> items) {
// 保存订单
orderMapper.insert(order);
// 保存订单项
for (OrderItem item : items) {
item.setOrderId(order.getId());
orderItemMapper.insert(item);
}
// 模拟异常,触发事务回滚
// int a = 1 / 0;
}
}
异常处理注解
用于全局统一处理接口异常,避免接口返回杂乱的异常信息。
@RestControllerAdvice
作用:全局异常处理注解,结合 @ExceptionHandler 使用,专门处理 @RestController 注解的控制器异常,返回 JSON 格式的异常信息。
示例:
java
// 全局异常处理器
@RestControllerAdvice
public class GlobalExceptionHandler {
// 处理自定义业务异常
@ExceptionHandler(BusinessException.class)
public Map<String, Object> handleBusinessException(BusinessException e) {
Map<String, Object> result = new HashMap<>();
result.put("code", 400);
result.put("message", e.getMessage());
return result;
}
// 处理所有未捕获的异常
@ExceptionHandler(Exception.class)
public Map<String, Object> handleException(Exception e) {
Map<String, Object> result = new HashMap<>();
result.put("code", 500);
result.put("message", "服务器内部错误:" + e.getMessage());
return result;
}
}
其他常用注解
1. @ResponseBody
作用:将方法返回值转换为 JSON / 字符串,直接写入 HTTP 响应体,单独使用时可加在 @Controller 注解的方法上(等同于 @RestController)。
示例:
java
@Controller
@RequestMapping("/api/test")
public class TestController {
// 单独使用 @ResponseBody,返回 JSON 数据
@GetMapping
@ResponseBody
public Map<String, String> test() {
Map<String, String> result = new HashMap<>();
result.put("msg", "success");
return result;
}
}
2. @CrossOrigin
作用:解决跨域问题,允许指定的域名访问当前接口,适用于前后端分离项目。
示例:
java
// 允许所有域名跨域访问该控制器的所有接口
@RestController
@RequestMapping("/api/users")
@CrossOrigin(origins = "*", maxAge = 3600)
public class UserController {
@GetMapping
public List<User> listUsers() {
List<User> users = new ArrayList<>();
users.add(new User(1L, "zhangsan", "123456"));
return users;
}
}
核心启动配置 :@SpringBootApplication、@Configuration 是项目启动的基础,必掌握;
组件注册 :@RestController、@Service、@Repository、@Autowired 是分层开发的核心,高频使用;
接口开发 :@GetMapping/@PostMapping、@PathVariable/@RequestParam/@RequestBody 是接口接收请求的核心;
配置读取 :简单配置用 @Value,复杂配置用 @ConfigurationProperties;
事务 & 异常 :@Transactional 保证数据一致性,@RestControllerAdvice 统一处理异常,是企业开发必备。
总结
- 核心本质:Spring Boot 是 Spring 框架的 "增强脚手架",核心是 "自动配置 + 起步依赖 + 内嵌服务器",解决传统 Spring 配置繁琐、依赖复杂的问题;
- 核心特性:约定大于配置、开箱即用、简化依赖管理、内置服务器、完善的配置体系;
- 开发思路:通过 Spring Initializr 快速建项目,基于注解开发业务逻辑,利用配置文件管理环境参数,最终打包为可执行 JAR 部署。
为 JSON / 字符串,直接写入 HTTP 响应体,单独使用时可加在 @Controller 注解的方法上(等同于 @RestController)。
示例:
java
@Controller
@RequestMapping("/api/test")
public class TestController {
// 单独使用 @ResponseBody,返回 JSON 数据
@GetMapping
@ResponseBody
public Map<String, String> test() {
Map<String, String> result = new HashMap<>();
result.put("msg", "success");
return result;
}
}
2. @CrossOrigin
作用:解决跨域问题,允许指定的域名访问当前接口,适用于前后端分离项目。
示例:
java
// 允许所有域名跨域访问该控制器的所有接口
@RestController
@RequestMapping("/api/users")
@CrossOrigin(origins = "*", maxAge = 3600)
public class UserController {
@GetMapping
public List<User> listUsers() {
List<User> users = new ArrayList<>();
users.add(new User(1L, "zhangsan", "123456"));
return users;
}
}
核心启动配置 :@SpringBootApplication、@Configuration 是项目启动的基础,必掌握;
组件注册 :@RestController、@Service、@Repository、@Autowired 是分层开发的核心,高频使用;
接口开发 :@GetMapping/@PostMapping、@PathVariable/@RequestParam/@RequestBody 是接口接收请求的核心;
配置读取 :简单配置用 @Value,复杂配置用 @ConfigurationProperties;
事务 & 异常 :@Transactional 保证数据一致性,@RestControllerAdvice 统一处理异常,是企业开发必备。
总结
- 核心本质:Spring Boot 是 Spring 框架的 "增强脚手架",核心是 "自动配置 + 起步依赖 + 内嵌服务器",解决传统 Spring 配置繁琐、依赖复杂的问题;
- 核心特性:约定大于配置、开箱即用、简化依赖管理、内置服务器、完善的配置体系;
- 开发思路:通过 Spring Initializr 快速建项目,基于注解开发业务逻辑,利用配置文件管理环境参数,最终打包为可执行 JAR 部署。
Spring Boot 是当前 Java 后端开发的主流框架,掌握其核心原理和开发方式,是从事企业级 Java 开发的必备技能。