前置基础
Spring Boot 的核心是约定大于配置,通过自动配置(AutoConfiguration) 消除 Spring 原生的繁琐 XML 配置,所有组件都基于Starter 起步依赖引入,只需少量配置(甚至零配置)即可使用。
- 核心依赖:
spring-boot-starter(基础核心),所有组件都基于此扩展; - 开发工具:
spring-boot-starter-devtools(热部署)、spring-boot-configuration-processor(配置提示);
Spring Boot 3.x 框架核心组件使用详解,涵盖 Starter 起步依赖、主启动类配置、配置文件属性绑定、Bean 注册与依赖注入注解、Web 开发(RESTful 接口、全局异常处理、拦截器、跨域)、数据访问(MyBatis-Plus、事务管理)及辅助工具(热部署、Lombok、Knife4j)。重点讲解自动配置原理、多环境配置、统一异常处理及数据库操作规范,提供可直接运行的代码示例,帮助开发者快速搭建企业级后端项目。
Spring Boot 的核心是约定大于配置,通过自动配置(AutoConfiguration) 消除 Spring 原生的繁琐 XML 配置,所有组件都基于Starter 起步依赖引入,只需少量配置(甚至零配置)即可使用。
spring-boot-starter(基础核心),所有组件都基于此扩展;spring-boot-starter-devtools(热部署)、spring-boot-configuration-processor(配置提示);Starter 是 Spring Boot 的组件依赖封装,将某个功能的所有相关依赖(如核心包、依赖包、配置包)整合为一个 Maven/Gradle 依赖,只需引入 1 个 Starter,即可自动引入该功能的所有必要依赖,避免手动管理依赖版本、解决依赖冲突。
spring-boot-starter-*(如spring-boot-starter-web),第三方 Starter 为*spring-boot-starter(如mybatis-spring-boot-starter);META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件,指定该组件的自动配置类,Spring Boot 启动时会自动加载。<!-- 基础核心 Starter(所有 Spring Boot 项目必加) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- Web 开发 Starter(MVC+Tomcat,后端接口必加) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 测试 Starter(Junit5+MockMvc,单元测试必加) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
Spring Boot 项目的入口类,通过注解开启自动配置、组件扫描、配置属性绑定三大核心功能,是项目启动的唯一入口。
// 核心复合注解,等价于以下三个注解的组合
// @SpringBootApplication = @SpringBootConfiguration + @EnableAutoConfiguration + @ComponentScan
@SpringBootConfiguration:继承自@Configuration,标记该类为配置类,可在类中用@Bean声明自定义组件;@EnableAutoConfiguration:开启自动配置,加载所有 Starter 的自动配置类,实现'零配置'使用组件;@ComponentScan:开启组件扫描,自动扫描当前包及其子包下的@Controller/@Service/@Repository/@Component注解类,将其注册为 Spring Bean。import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
// 注解加在主类上,扫描包:com.example.demo 及其所有子包
@SpringBootApplication
// 可选:指定扫描包(若主类不在项目根包,需手动指定)
// @SpringBootApplication(scanBasePackages = "com.example")
public class SpringBootComponentDemoApplication {
// 项目启动入口方法,固定写法
public static void main(String[] args) {
// 启动 Spring Boot 应用,返回 Spring 容器(ApplicationContext)
SpringApplication.run(SpringBootComponentDemoApplication.class, args);
}
}
主启动类建议放在项目根包(如com.example.demo),否则需用scanBasePackages手动指定扫描包,否则子包的组件无法被 Spring 扫描并注册。
Spring Boot 的全局配置文件,用于覆盖组件的默认自动配置(如端口、数据库连接、日志级别),支持yml(推荐,层级清晰) 和properties(键值对) 两种格式,项目启动时会自动加载src/main/resources/下的该文件。
application-dev.yml(开发环境) > application-prod.yml(生产环境) > application.yml(全局默认),可通过多环境配置切换不同环境的配置。
# 服务器配置(覆盖 spring-boot-starter-web 的默认配置)
server:
port: 8081 # 项目启动端口,默认 8080
servlet:
context-path: /demo # 接口上下文路径,默认/,访问时需加/demo(如 http://localhost:8081/demo/hello)
# Spring 核心配置
spring:
application:
name: spring-boot-component-demo # 项目名称,服务注册/日志中会使用
application-dev.yml(本地开发,端口 8081,日志级别 DEBUG)application-prod.yml(线上部署,端口 80,日志级别 INFO)application.yml中指定激活的环境:spring:
profiles:
active: dev # 激活开发环境,改为 prod 即切换到生产环境
开发中常需要自定义配置(如自定义接口前缀、业务常量),Spring Boot 提供两种方式绑定到 Java 类:
**方式 2:@ConfigurationProperties(复杂配置,批量绑定)**适合多个相关自定义属性(如微信配置、OSS 配置),批量绑定到一个配置类,更规范、支持配置提示:
步骤 1:编写配置类,添加注解:
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
// 组件注解:将该类注册为 Spring Bean
@Component
// 配置前缀:绑定 yml 中的 wechat 节点下的所有属性
@ConfigurationProperties(prefix = "wechat")
public class WechatProperties {
// 与 yml 中的属性名一致(驼峰自动匹配横杠命名:app-id → appId)
private String appId;
private String appSecret;
private String mchId; // 商户号
// 必须提供 getter/setter,否则无法绑定(Lombok 的@Data可自动生成)
public String getAppId() { return appId; }
public void setAppId(String appId) { this.appId = appId; }
public String getAppSecret() { return appSecret; }
public void setAppSecret(String appSecret) { this.appSecret = appSecret; }
public String getMchId() { return mchId; }
public void setMchId(String mchId) { this.mchId = mchId; }
}
步骤 2:yml 中添加对应配置:
# 微信配置
wechat:
app-id: wx1234567890abcdef
app-secret: 1234567890abcdef1234567890abcdef
mch-id: 1234567890
步骤 3:在业务类中注入使用:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class WechatController {
// 注入配置类
@Autowired
private WechatProperties wechatProperties;
@GetMapping("/wechat/info")
public String wechatInfo() {
return "微信 AppId:" + wechatProperties.getAppId() + ",商户号:" + wechatProperties.getMchId();
}
}
步骤 4:添加配置提示依赖(可选,IDEA 中显示配置注解,避免手敲错误):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
**方式 1:@Value(简单配置,单个属性绑定)**适合单个 / 少量自定义属性,直接在 Bean 中注入:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
// 绑定 yml 中的自定义配置:app.api-prefix
@Value("${app.api-prefix:/api/v1}") // 冒号后为默认值,若配置中无该属性则使用默认值
private String apiPrefix;
@GetMapping("/hello")
public String hello() {
return "Hello Spring Boot! 接口前缀:" + apiPrefix;
}
}
对应的 yml 配置:
# 自定义配置
app:
api-prefix: /api/v2
Spring Boot 的所有组件都基于Spring IOC 容器,核心是将对象交给 Spring 管理(Bean 注册) + 从 Spring 容器中获取对象(依赖注入),以下是最核心的注解,所有业务开发都离不开:
标记在类上,Spring 启动时会自动扫描并创建该类的实例,存入 IOC 容器,全局唯一(默认单例)。
| 注解 | 作用 | 适用场景 |
|---|---|---|
@Component | 通用 Bean 注册注解 | 通用工具类、非业务层类 |
@Controller | 继承自 @Component,标记控制层 | 接口请求处理类(接收请求、返回响应) |
@Service | 继承自 @Component,标记服务层 | 业务逻辑处理类(核心业务、事务控制) |
@Repository | 继承自 @Component,标记数据访问层 | 数据库操作类(DAO/Mapper,MyBatis 中一般用 @Mapper 替代) |
@Configuration | 标记配置类 | 声明自定义 Bean(如第三方组件配置、拦截器配置) |
标记在字段 / 构造方法 /setter 方法上,Spring 会自动从 IOC 容器中找到对应的 Bean,注入到当前类中,无需手动new对象,实现解耦。
| 注解 | 作用 | 特点 |
|---|---|---|
@Autowired | 按类型注入 Bean | Spring 核心注解,自动匹配类型,支持required = false(非必须注入) |
@Resource | 按名称注入 Bean(JDK 原生) | 若有多个同类型 Bean,可通过name指定,如@Resource(name = "userServiceImpl") |
@Qualifier | 配合 @Autowired,按名称注入 | 解决同类型多个 Bean 的注入问题,如@Autowired + @Qualifier("userServiceImpl") |
标记在配置类的方法上,用于将第三方组件 / 无注解的类注册为 Spring Bean(如 RedisTemplate、RestTemplate),方法返回值即为 Bean 实例,方法名为 Bean 名称。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
// 配置类
@Configuration
public class WebConfig {
// 声明 RestTemplate 为 Spring Bean,全局可注入使用
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
使用时直接注入:
@Autowired
private RestTemplate restTemplate; // 无需 new,直接使用
基于spring-boot-starter-web,实现 RESTful 接口开发,包含MVC 核心、请求处理、响应处理、拦截器、跨域等,是后端开发最核心的组件。
@RestController = @Controller + @ResponseBody:返回 JSON 数据(RESTful 接口首选),所有方法的返回值都会自动序列化为 JSON,无需手动加 @ResponseBody;@Controller:返回视图(传统 SSM 开发,如 JSP/Thymeleaf),适合前后端不分离项目,若需返回 JSON,需在方法上加@ResponseBody。import org.springframework.web.bind.annotation.*;
// 标记为 RestController,所有方法返回 JSON
@RestController
// 类级别的请求路径,所有方法的路径都基于此(如/hello → /user/hello)
@RequestMapping("/user")
public class UserController {
// GET 请求:查询用户,路径/ user /get/{id}(路径参数)
@GetMapping("/get/{id}")
// @PathVariable:获取 URL 路径中的参数
public String getUser(@PathVariable Long id) {
return "{\"id\":" + id + ", \"name\":\"张三\", \"age\":25}";
}
// POST 请求:新增用户,接收 JSON 参数
@PostMapping("/add")
// @RequestBody:将请求体的 JSON 字符串绑定到 User 对象(自动反序列化)
public String addUser(@RequestBody User user) {
return "新增用户成功:" + user.getName();
}
// GET 请求:分页查询,接收请求参数(如/page?pageNum=1&pageSize=10)
@GetMapping("/page")
// @RequestParam:获取请求参数,支持默认值
public String pageQuery(@RequestParam Integer pageNum, @RequestParam(defaultValue = "10") Integer pageSize) {
return "分页查询:第" + pageNum + "页,每页" + pageSize + "条";
}
}
// 实体类(配合@RequestBody 使用,需提供 getter/setter,Lombok@Data可简化)
class User {
private Long id;
private String name;
private Integer age;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public Integer getAge() { return age; }
public void setAge(Integer age) { this.age = age; }
}
都是@RequestMapping的简化版,指定请求方式,避免在 @RequestMapping 中手动设置method = RequestMethod.GET:
@GetMapping:处理 GET 请求(查询)@PostMapping:处理 POST 请求(新增)@PutMapping:处理 PUT 请求(修改)@DeleteMapping:处理 DELETE 请求(删除)@PatchMapping:处理 PATCH 请求(局部修改)统一处理项目中所有的未捕获异常,避免接口返回默认的 500 错误页面 / 杂乱的异常信息,返回统一的 JSON 格式响应,提升接口的友好性和可维护性。
@RestControllerAdvice:全局异常处理类注解,继承自@ControllerAdvice,配合@ExceptionHandler使用,返回 JSON 数据;@ExceptionHandler:标记异常处理方法,指定处理的异常类型(如Exception.class处理所有异常,NullPointerException.class处理空指针异常)。import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.HashMap;
import java.util.Map;
// 全局异常处理,作用于所有@RestControllerr
@RestControllerAdvice
public class GlobalExceptionHandler {
// 处理所有未捕获的异常(兜底)
@ExceptionHandler(Exception.class)
public Map<String, Object> handleAllException(Exception e) {
Map<String, Object> result = new HashMap<>();
result.put("code", HttpStatus.INTERNAL_SERVER_ERROR.value()); // 500
result.put("msg", "服务器内部错误:" + e.getMessage()); // 异常信息
result.put("data", null);
return result;
}
// 处理自定义业务异常(推荐,项目中自定义异常,精准处理)
@ExceptionHandler(BusinessException.class)
public Map<String, Object> handleBusinessException(BusinessException e) {
Map<String, Object> result = new HashMap<>();
result.put("code", e.getCode()); // 自定义错误码
result.put("msg", e.getMsg()); // 自定义错误信息
result.put("data", null);
return result;
}
// 处理空指针异常(精准处理特定异常)
@ExceptionHandler(NullPointerException.class)
public Map<String, Object> handleNPE(NullPointerException e) {
Map<String, Object> result = new HashMap<>();
result.put("code", 400);
result.put("msg", "空指针异常:" + e.getMessage());
result.put("data", null);
return result;
}
}
// 自定义业务异常(项目中建议创建,用于业务逻辑错误)
class BusinessException extends RuntimeException {
private Integer code;
private String msg;
public BusinessException(Integer code, String msg) {
super(msg);
this.code = code;
this.msg = msg;
}
public Integer getCode() { return code; }
public String getMsg() { return msg; }
}
@Service
public class UserService {
public void deleteUser(Long id) {
if (id == null || id <= 0) {
// 抛出自定义业务异常,由全局异常处理器处理
throw new BusinessException(400, "用户 ID 不合法");
}
// 业务逻辑:删除用户
}
}
拦截接口请求,在请求处理前、处理后、视图渲染后(Rest 接口无此步骤) 执行自定义逻辑,如登录验证、接口限流、日志记录、参数校验等。
HandlerInterceptor接口,重写拦截方法;WebMvcConfigurer接口,重写addInterceptors方法,注册拦截器并指定拦截 / 放行路径。// 步骤 1:实现 HandlerInterceptor,编写拦截逻辑
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginInterceptor implements HandlerInterceptor {
// 核心方法:请求处理前执行(return true:放行,return false:拦截)
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 逻辑:从请求头获取 token,验证是否登录
String token = request.getHeader("token");
if (token == null || token.isEmpty()) {
// 未登录,返回 401 错误
response.setStatus(401);
response.getWriter().write("{\"code\":401, \"msg\":\"未登录,请先登录\", \"data\":null}");
return false; // 拦截请求
}
// 登录验证通过,放行
return true;
}
// 可选:请求处理后执行(控制器方法执行完,未返回响应前)
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, org.springframework.web.servlet.ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
// 可选:视图渲染后执行(Rest 接口无需实现)
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
// 步骤 2:配置类中注册拦截器
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
// 注册拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/**") // 拦截所有路径
.excludePathPatterns("/user/login", "/user/register"); // 放行登录/注册接口
}
}
解决前后端分离项目中的跨域问题(浏览器同源策略限制:协议、域名、端口任一不同即为跨域,如前端 http://localhost:3000 访问后端 http://localhost:8081)。
在WebMvcConfig中重写addCorsMappings方法:
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
// 全局跨域配置
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // 允许所有路径跨域
.allowedOriginPatterns("*") // 允许所有域名跨域(Spring Boot 2.4+替代 allowedOrigins("*"))
.allowedMethods("GET", "POST", "PUT", "DELETE", "PATCH") // 允许的请求方式
.allowedHeaders("*") // 允许的请求头
.allowCredentials(true) // 允许携带 Cookie
.maxAge(3600); // 预检请求有效期(秒),避免重复发送预检请求
}
// 拦截器注册...
}
用@CrossOrigin注解,标记在控制器 / 方法上:
// 控制器级别:该类所有接口允许跨域
@RestController
@RequestMapping("/user")
@CrossOrigin(origins = "*", maxAge = 3600)
public class UserController {
// 方法级别:仅该接口允许跨域(覆盖控制器级别配置)
@GetMapping("/get/{id}")
@CrossOrigin(origins = "http://localhost:3000")
public String getUser(@PathVariable Long id) {
return "{\"id\":" + id + ", \"name\":\"张三\"}";
}
}
Spring Boot 提供了多种数据访问组件,适配不同的数据库操作框架,最常用的是 MyBatis-Plus(简化 MyBatis) 和Spring Data JPA(ORM 框架),以下讲解基于MyBatis-Plus(企业开发主流,比原生 MyBatis 少写 80% 代码)。
<!-- MyBatis-Plus Starter(整合 MyBatis+ 自动配置) -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.5</version> <!-- 最新稳定版 -->
</dependency>
<!-- MySQL 驱动(适配 MySQL8+,5.x 需修改版本为 5.1.49) -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!-- 阿里 Druid 连接池(高性能,推荐,替代默认的 HikariCP) -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.20</version>
</dependency>
配置数据库连接、MyBatis-Plus、连接池参数:
spring:
# 数据库连接配置
datasource:
type: com.alibaba.druid.pool.DruidDataSource # 指定 Druid 连接池
driver-class-name: com.mysql.cj.jdbc.Driver # MySQL8+ 驱动类
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
username: root # 数据库用户名
password: 123456 # 数据库密码
# Druid 连接池配置
druid:
initial-size: 5 # 初始连接数
min-idle: 5 # 最小空闲连接数
max-active: 20 # 最大活跃连接数
max-wait: 60000 # 最大等待时间(ms)
# MyBatis-Plus 配置
mybatis-plus:
mapper-locations: classpath:mapper/*.xml # Mapper.xml 文件路径(若用注解开发可省略)
type-aliases-package: com.example.demo.entity # 实体类包名,简化 XML 中的类名
configuration:
map-underscore-to-camel-case: true # 开启下划线转驼峰(数据库 user_name → 实体类 userName)
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 开启 SQL 日志,方便调试
标记实体类与数据库表的映射关系:
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
// 映射数据库表:t_user(若实体类名与表名一致,可省略)
@TableName("t_user")
public class User {
// 主键注解,type = IdType.AUTO:自增主键
@TableId(type = IdType.AUTO)
private Long id;
// 字段注解,若实体类属性与表字段名一致,可省略
@TableField("user_name")
private String userName;
private Integer age;
private String email;
// getter/setter...
}
MyBatis-Plus 的核心,继承BaseMapper<T>即可获得单表 CRUD 所有方法,无需手动编写 Mapper 接口和 XML:
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.entity.User;
import org.apache.ibatis.annotations.Mapper;
// 标记为 MyBatis Mapper,Spring Boot 自动扫描并注册
@Mapper
public interface UserMapper extends BaseMapper<User> {
// 无需编写任何方法,BaseMapper 已提供所有单表 CRUD
// 若需复杂查询,可手动编写方法+XML/注解
}
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.demo.entity.User;
import com.example.demo.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
// 新增用户
public boolean addUser(User user) {
return userMapper.insert(user) > 0;
}
// 根据 ID 查询用户
public User getUserById(Long id) {
return userMapper.selectById(id);
}
// 条件查询:根据姓名模糊查询,年龄大于 20
public List<User> listUser(String name) {
// LambdaQueryWrapper:条件构造器,链式编程,避免硬编码字段名
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.like(User::getUserName, name) // 姓名模糊查询
.gt(User::getAge, 20); // 年龄大于 20
return userMapper.selectList(wrapper);
}
// 修改用户
public boolean updateUser(User user) {
return userMapper.updateById(user) > 0;
}
// 删除用户
public boolean deleteUser(Long id) {
return userMapper.deleteById(id) > 0;
}
}
保证多个数据库操作的原子性(要么全部成功,要么全部失败),避免出现数据不一致(如转账时扣了 A 的钱,没加 B 的钱)。
标记在服务层方法上(必须在服务层,控制器层无效),Spring 会自动为该方法添加事务支持:
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
// 新增用户并记录日志,开启事务
// rollbackFor = Exception.class:所有异常都回滚(默认仅运行时异常回滚)
@Transactional(rollbackFor = Exception.class)
public boolean addUserAndLog(User user) {
// 操作 1:新增用户
userMapper.insert(user);
// 模拟异常:若出现异常,事务回滚,用户不会被新增
// int i = 1 / 0;
// 操作 2:记录日志(假设有 LogMapper)
// logMapper.insert(new Log("新增用户:" + user.getUserName()));
return true;
}
}
rollbackFor = Exception.class:指定所有异常都回滚(默认仅RuntimeException和Error回滚,编译时异常如IOException不回滚,建议必加);propagation:事务传播行为(如REQUIRED:默认,有事务则加入,无则新建;SUPPORTS:有事务则加入,无则无事务);readOnly = true:只读事务(仅查询,提升性能)。修改代码 / 配置后,无需手动重启项目,自动重启 Spring Boot 应用,提升开发效率(仅开发环境使用,生产环境禁用)。
<!-- 热部署依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
yml 配置(可选,优化热部署):
spring:
devtools:
restart:
enabled: true # 开启热部署
additional-paths: src/main/java # 监听的代码目录
exclude: static/**,templates/** # 排除的目录(静态资源/视图,修改后无需重启)
IDEA 配置(必做,否则热部署不生效):
Ctrl+Alt+Shift+/ → 选择 Registry → 勾选compiler.automake.allow.when.app.running。通过注解替代 Java 中繁琐的getter/setter/toString/ 构造方法,减少代码量,提升开发效率(需安装 IDEA Lombok 插件)。
<!-- Lombok 依赖 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
常用注解(标记在实体类上):
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
import lombok.ToString;
@TableName("t_user")
@Data // 自动生成 getter/setter/equals/hashCode/toString
@NoArgsConstructor // 自动生成无参构造方法
@AllArgsConstructor // 自动生成全参构造方法
// @ToString // 单独生成 toString(@Data 已包含)
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String userName;
private Integer age;
private String email;
}
其他常用注解:
@Slf4j:自动生成日志对象log,替代LoggerFactory.getLogger(类名.class);@Builder:开启建造者模式,可通过User.builder().id(1L).userName("张三").build()创建对象;@NonNull:标记字段为非空,赋值为 null 时抛出空指针异常。自动生成RESTful 接口文档,支持在线调试、接口测试、文档导出,替代传统的 Word 文档,实现接口文档与代码同步更新(Swagger3 的增强版,更适配 Spring Boot 3+)。
<!-- Knife4j Starter(整合 Swagger3,适配 Spring Boot 3+) -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>4.4.0</version> <!-- 最新稳定版 -->
</dependency>
配置类(开启 Swagger3):
import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
@Configuration
@EnableWebMvc
@EnableKnife4j // 开启 Knife4j 增强功能
public class Knife4jConfig {
// 配置接口文档基本信息
@Bean
public OpenAPI openAPI() {
return new OpenAPI()
.info(new Info()
.title("Spring Boot 组件演示接口文档")
.description("Spring Boot 核心组件实战接口")
.version("1.0.0"));
}
}
yml 配置(开发环境开启,生产环境关闭):
knife4j:
enable: true # 开启 Knife4j
openapi:
title: Spring Boot 组件演示接口文档
description: 核心组件实战接口
version: 1.0.0
spring:
profiles:
active: dev # 开发环境开启,生产环境改为 prod 并设置 knife4j.enable=false
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/user")
public class UserController {
// 接口描述
@Operation(summary = "根据 ID 查询用户", description = "传入用户 ID,返回用户详细信息")
// 参数描述
@Parameters({@Parameter(name = "id", description = "用户 ID", required = true)})
@GetMapping("/get/{id}")
public User getUser(@PathVariable Long id) {
return new User(id, "张三", 25, "[email protected]");
}
}
项目启动后,访问:http://localhost:8081/doc.html(替换为自己的端口 / 上下文路径),即可看到接口文档,支持在线调试(直接填写参数,点击'发送'即可测试接口)。
┌─────────────────────────────────────────────────────────┐
│ 客户端请求(浏览器/前端/Postman) │
└───────────────────────────┬─────────────────────────────┘
│
┌───────────────────────────▼─────────────────────────────┐
│ 服务器(Tomcat,由 spring-boot-starter-web 自动嵌入) │
└───────────────────────────┬─────────────────────────────┘
│
┌───────────────────────────▼─────────────────────────────┐
│ 拦截器(Interceptor):登录验证/日志记录/限流 │
└───────────────────────────┬─────────────────────────────┘
│
┌───────────────────────────▼─────────────────────────────┐
│ 控制器(@RestController):接收请求/参数绑定/返回响应 │
└───────────────────────────┬─────────────────────────────┘
│
┌───────────────────────────▼─────────────────────────────┐
│ 服务层(@Service):业务逻辑处理 + 事务管理(@Transactional)│
└───────────────────────────┬─────────────────────────────┘
│
┌───────────────────────────▼─────────────────────────────┐
│ 数据访问层(@Mapper/MyBatis-Plus):操作数据库 │
└───────────────────────────┬─────────────────────────────┘
│
┌───────────────────────────▼─────────────────────────────┐
│ 数据库(MySQL/Redis) │
└─────────────────────────────────────────────────────────┘
全局组件兜底:
以上就是 Spring Boot 最核心、最常用的组件使用详解,覆盖了从基础项目搭建到后端接口开发、数据库操作、效率提升的全流程,所有代码都可直接复制到 Spring Boot 3.2.x 项目中使用,适配企业开发的主流场景。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online