SpringBoot 学习
什么是 SpringBoot
SpringBoot 是基于 Spring 生态的开源框架,旨在简化 Spring 应用的初始化搭建和开发配置。它通过约定大于配置的理念,提供快速构建生产级应用的解决方案,显著降低开发者对 XML 配置和依赖管理的负担。
特点:
-
快速创建独立 Spring 应用。
-
直接嵌入 Tomcat、Jetty or Undertow(无需部署 war 包)(Servlet容器)。
-
提供可选的 starter,简化应用整合。
-
按需自动配置 Spring 以及第三方库。
-
提供生产级特性:如 监控指标、健康检查、外部化配置等。
-
无代码生成、无xml。
核心特性
- 自动配置
- 原理:根据项目依赖的 JAR 包(如
spring-boot-starter-data-jpa
),自动推断并配置所需的 Bean(如数据源、事务管理器等)。 - 示例:引入
spring-boot-starter-web
后,自动配置内嵌 Tomcat、Spring MVC 和 Jackson 库。 - 自定义:通过
application.properties
或@Configuration
类覆盖默认配置。
- 原理:根据项目依赖的 JAR 包(如
- 起步依赖
- 作用:将功能相关的依赖打包成一组(如
spring-boot-starter-data-redis
),解决版本冲突问题。 - 本质:基于 Maven/Gradle 的依赖传递机制,简化
pom.xml
或build.gradle
配置。
- 作用:将功能相关的依赖打包成一组(如
- 内嵌服务器
- 支持服务器:Tomcat(默认)、Jetty、Undertow。
- 优势:无需部署 WAR 包到外部服务器,直接通过
main()
方法运行 JAR 文件。
- 生产就绪功能
- 集成 Spring Boot Actuator:提供监控端点(如
/health
,/metrics
),支持应用性能追踪和健康检查。 - 外部化配置:支持多环境配置(如
application-dev.yml
,application-prod.yml
)。
- 集成 Spring Boot Actuator:提供监控端点(如
为什么会出现 SpringBoot
- 传统 Spring 的痛点
- 繁琐的 XML 配置和重复的注解配置。
- 依赖版本冲突频繁,需手动协调。
- 部署依赖外部服务器,开发效率低。
- Spring Boot 的优化
- 零 XML 配置,通过注解和默认配置简化开发。
- 起步依赖统一管理版本,避免冲突。
- 内嵌服务器实现“一键启动”。
核心组件
- 启动流程
@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}
@SpringBootApplication
组合了三个注解:@SpringBootConfiguration
:标识为配置类。@EnableAutoConfiguration
:启用自动配置。@ComponentScan
:扫描当前包及子包的组件。
SpringApplication.run()
启动内嵌服务器,加载自动配置类。
- 条件装配(Conditional)
Spring Boot 通过 @ConditionalOnClass
、@ConditionalOnMissingBean
等注解,动态判断是否装配某个 Bean。例如:
- 当类路径存在
DataSource.class
时,才自动配置数据源。 - 当容器中无自定义的
DataSource
Bean 时,使用默认配置。
应用场景
-
快速构建 RESTful API
使用
@RestController
和spring-boot-starter-web
,几分钟内完成 API 开发与测试。 -
微服务开发
作为 Spring Cloud 微服务架构的基础,轻松整合服务注册(Eureka)、配置中心(Config)等功能。
-
批处理任务
结合
spring-boot-starter-batch
实现定时任务或大数据处理。 -
数据驱动应用
整合 JPA(
spring-boot-starter-data-jpa
)或 MyBatis,快速操作数据库。
SpringBoot 与 Spring 关系
对比项 | Spring | Spring Boot |
---|---|---|
定位 | 基础框架,提供 IOC、AOP、事务管理等核心功能 | Spring 的扩展,简化配置和开发流程 |
配置方式 | 需手动配置 XML 或 Java Config | 约定大于配置,自动装配为主 |
依赖管理 | 需开发者自行解决依赖冲突 | 通过 Starter 管理依赖和版本 |
部署 | 依赖外部服务器(如 Tomcat) | 内嵌服务器,打包为可执行 JAR |
优缺点
- 优点
- 快速上手,适合新手和快速原型开发。
- 生态丰富,与 Spring Cloud、Spring Security 无缝整合。
- 社区活跃,文档完善。
- 缺点
- 过度依赖自动配置,可能隐藏底层细节(需理解原理以调试复杂问题)。
- 大型项目可能需要自定义配置覆盖默认行为。
总结
简化开发,简化配置,简化整合,简化部署,简化监控,简化运维。
快速开始
场景:快速开发一个 SpringBoot Web 工程。
快速搭建一个 SpringBoot 项目有两种方式:
SpringBoot 3 要求的 jdk 最低版本为 17。
创建 Maven 项目,转成 SpringBoot 项目
步骤:
- 创建一个 Maven 项目。
- 在
pom.xml
文件导入一个父工程(SpringBoot 项目)。
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.4.4</version>
</parent>
- 导入 SpringBoot Web 依赖:
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
</dependencies>
这个依赖不需要指定版本号。
- 创建 SpringBoot 主程序:
@SpringBootApplication
public class MainApplication {public static void main(String[] args) {SpringApplication.run(MainApplication.class, args);}}
要在类上添加注解 @SpringBootApplication
。
- 在主程序所在包下创建
controller
层:
@RestController
public class HelloController {@GetMapping("/hello")public String hello(){return "Hello SpringBoot";}}
- 启动项目,访问
localhost:8080/hello
进行测试,出现hello SpringBoot
成功。
如果想要打成 jar 包,需要在 pom.xml
导入插件依赖:
<build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins>
</build>
使用 Spring 初始化工具直接创建 SpringBoot 项目
- 使用初始化工具创建 SpringBoot 项目:
新版 idea 是 Spring Boot,老版是 Spring Initializr。
项目名自行取即可。
- 点 next 下一步,选中 Web 模块。
选中模块后 SpringBoot 项目会自动导入相应的模块。
创建好的项目可以看到 pom.xml
和主程序已经编写好了,我们只需要编写 controller
层即可。
pom.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.4.4</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.yigongsui</groupId><artifactId>springboot-study</artifactId><version>0.0.1-SNAPSHOT</version><name>springboot-study</name><description>springboot-study</description><url/><licenses><license/></licenses><developers><developer/></developers><scm><connection/><developerConnection/><tag/><url/></scm><properties><java.version>17</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
主程序:
package com.yigongsui.springbootstudy;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class SpringbootStudyApplication {public static void main(String[] args) {SpringApplication.run(SpringbootStudyApplication.class, args);}}
之后步骤同上面。
简单介绍自动创建的 pom.xml
各标签信息(了解即可)
-
<url>
(根级别):项目基础信息。- 表示项目主页 URL。
- 示例:
<url>https://github.com/yourname/project</url>
。 - 用于生成项目文档链接。
-
<license>
:许可证信息,需包含:<name>
:许可证名称(如 MIT License)。<url>
:许可证文本地址。<distribution>
:分发方式(通常为"repo")。
-
<developers>
:开发者信息:- 支持多开发者声明。
- 包含开发者身份识别和联系方式。
<developers><developer><id>dev001</id><name>张三</name><email>zhangsan@example.com</email><roles><role>架构师</role></roles></developer> </developers>
-
<scm>
:版本控制配置connection
:只读访问路径。developerConnection
:开发者提交权限路径。- 协议差异:
https
:匿名只读访问。ssh
:需认证的读写访问。
<tag>
标记当前代码版本。
starter 概述
定义与作用
-
简化依赖管理
SpringBoot starter 是预定义的依赖描述模板(
pom.xml
或build.gradle
片段),通过约定大于配置原则,将特定功能所需的多组依赖库整合为单一依赖项,核心原理是依赖传递。示例:引入
spring-boot-starter-web
会自动包含 Spring MVC、Tomcat、Jackson 等 Web 开发基础依赖。 -
自动配置机制
每个 starter 包含一个
spring.factories
文件,声明了关联的自动配置类(如WebMvcAutoConfiguration
)。SpringBoot启动时通过@EnableAutoConfiguration
扫描这些配置类,根据条件注解(如@ConditionalOnClass
)动态创建 Bean。
核心原理
-
依赖传递逻辑
<!-- 引入starter-web --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency>
实际会传递依赖:
spring-boot-starter
(核心启动器)spring-boot-starter-json
spring-webmvc
tomcat-embed-core
-
自动配置流程
@Configuration @ConditionalOnClass({ Servlet.class, DispatcherServlet.class }) @AutoConfigureAfter(ServletWebServerFactoryAutoConfiguration.class) public class WebMvcAutoConfiguration {// 自动配置DispatcherServlet、视图解析器等组件 }
常见 starter 分类
类型 | 示例 | 功能描述 |
---|---|---|
官方标准 starter | spring-boot-starter-data-jpa | 集成 JPA 与 Hibernate |
技术整合 starter | spring-boot-starter-security | 添加安全认证与授权功能 |
第三方 starter | mybatis-spring-boot-starter | MyBatis orm 框架集成 |
自定义 Starter 开发步骤
-
创建模块结构
my-starter/ ├── src/main/java │ └── com/example/autoconfigure │ ├── MyServiceAutoConfiguration.java // 自动配置类 │ └── MyServiceProperties.java // 配置属性绑定 └── src/main/resources└── META-INF└── spring.factories // 注册自动配置
-
实现自动配置类
@Configuration @EnableConfigurationProperties(MyServiceProperties.class) @ConditionalOnClass(MyService.class) public class MyServiceAutoConfiguration {@Bean@ConditionalOnMissingBeanpublic MyService myService(MyServiceProperties properties) {return new MyService(properties.getConfig());} }
-
配置属性绑定
@ConfigurationProperties(prefix = "my.service") public class MyServiceProperties {private String config = "default";// getters & setters }
-
注册自动配置
spring.factories
内容:org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.example.autoconfigure.MyServiceAutoConfiguration
最佳实践与注意事项
-
依赖范围控制
使用
<optional>true</optional>
标记非必要传递依赖,避免污染用户项目的依赖树。 -
条件注解使用
合理应用
@ConditionalOnProperty
、@ConditionalOnWebApplication
等注解,确保配置仅在满足条件时生效。 -
调试技巧
启动时添加
--debug
参数可查看自动配置报告。
通过 starter 机制,SpringBoot 实现了开箱即用的体验,开发者无需手动管理复杂依赖关系与 xml 配置,显著提升了开发效率。
SpringBoot 依赖管理机制
SpringBoot 通过统一版本管理和模块化 Starter 设计实现高效的依赖管理:
-
版本管理
-
维护了
spring-boot-dependencies
BOM(Bill of Materials),预定义了所有官方支持的依赖版本 -
开发者无需手动指定依赖版本号,例如:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><!-- 无需写<version> --> </dependency>
-
所有 Starter 的版本由 SpringBoot 父 POM 统一控制。
-
-
Starter 设计模式
- 每个 Starter 是一个功能聚合包,例如:
spring-boot-starter-web
:聚合 Spring MVC + Tomcat + JSON 处理等。spring-boot-starter-data-jpa
:聚合 Hibernate + Spring Data JPA。
- Starter 间通过
META-INF/spring.provides
声明依赖关系。 - Starter 命名规则:
- 官方命名:
spring-boot-starter-{功能模块}
,例如spring-boot-starter-web
。 - 第三方:
{技术名称}-spring-boot-starter
,例如mybatis-spring-boot-starter
。
- 官方命名:
- 每个 Starter 是一个功能聚合包,例如:
依赖管理实现方式
- 继承父项目
spring-boot-starter-parent
(推荐,就是快速开始的第一个项目)
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.1.0</version>
</parent>
- 自动获得:
- 默认 JDK 版本(Java 17)
- 资源文件编码(UTF-8)
- 依赖管理(
dependencyManagement
)
- 导入 BOM(非继承场景)
<dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>3.1.0</version><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement>
版本覆盖机制
当需要自定义依赖版本时:
<properties><mysql.version>8.0.33</mysql.version> <!-- 覆盖Spring Boot默认的MySQL驱动版本 -->
</properties>
- 优先级:项目指定版本 > BOM版本
- 风险提示:覆盖版本可能导致兼容性问题
依赖排除技术
处理冲突依赖的典型场景,例如 Web 模块排除 Tomcat:
<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>
- 此时可手动添加其他 Servlet 容器依赖(如 Jetty)
自动配置联动
依赖管理与自动配置的协同工作:
- 当引入
spring-boot-starter-data-redis
时:- 自动加入 Jedis、Lettuce 客户端。
- 自动配置
RedisTemplate
Bean。
- 条件化配置原理:
- 通过
@ConditionalOnClass
检测类路径是否存在特定类。 - 示例:当存在
DataSource.class
时,自动配置数据库连接池。
- 通过
优势总结
特性 | 传统 Spring 项目 | SpringBoot 项目 |
---|---|---|
依赖版本管理 | 手动维护各依赖版本 | 统一版本仲裁 |
功能模块集成 | 需逐个添加相关依赖 | 通过 Starter 一键集成 |
配置复杂度 | 需要显式配置 Bean | 基于依赖的自动配置 |
启动速度 | 较慢(需加载所有配置) | 更快(条件化配置按需加载) |
SpringBoot 自动配置机制
SpringBoot 的自动配置是其核心特性之一,通过智能推断和条件化加载 Bean 定义,大幅简化了手动配置的复杂度,核心是条件化加载 + 约定大于配置。
核心目标
- 零配置启动:根据项目依赖(如类路径中的 JAR 包)自动配置 Spring 应用。
- 按需加载:仅当满足特定条件(如类存在、Bean 未定义等)时,才启用相关配置。
- 可覆盖性:允许开发者通过显式配置或属性文件覆盖默认行为。
初步认识
自动配置
我们在编写 ssm 项目,都要自己导入相关的配置,例如 springmvc 的 DispatcherServlet
等,但在 SpringBoot 项目,则不需要导入这些配置,这是因为 SpringBoot 已经导入大量的相关配置类,我们可以通常这个代码查看 SpringBoot 都导入了哪些 bean:
ConfigurableApplicationContext ioc = SpringApplication.run(SpringbootStudyApplication.class, args);
String[] names = ioc.getBeanDefinitionNames();
for (String name : names) {System.out.println(name);
}
可以看到,像是 DispatcherServlet
以及我们编写的 helloController
都已经导入到 IoC 容器了。
默认包扫描
在 ssm 时,我们需要在主配置类下扫描 controller
层,service
层,dao
层,这些组件才会注入到容器内,但是在 SpringBoot 中,我们并没有扫描包,这些组件也被注入了。
这是因为 SpringBoot 的主程序类的注解 @SpringBootApplication
。
这个注解主要由三个注解组成:@SpringBootConfiguration
、@EnableAutoConfiguration
、@ComponentScan
。
会自动扫描主程序所在的包及其下面的子包。
也可以自定义扫描路径:
@SpringBootApplication(scanBasePackages = {"",""})
或
@ComponentScan({"",""})
默认配置值
SpringBoot 还编写了大量的默认配置属性,例如 Tomcat 启动的端口号是 8080。
-
配置文件的所有配置项是和某个类的对象值进行一一绑定的。
-
绑定了配置文件中每一项值的类: 属性类。
-
比如:
-
ServerProperties
绑定了所有 Tomcat 服务器有关的配置。 -
MultipartProperties
绑定了所有文件上传相关的配置。
-
如果想要修改默认值,在 SpringBoot 的资源文件 application.properties
下编写:
server.port=8888
官方配置的默认值参照:官方文档
按需加载自动配置
-
导入场景
spring-boot-starter-web
。 -
场景启动器除了会导入相关功能依赖,导入一个
spring-boot-starter
,是所有starter
的starter
,基础核心 starter。 -
spring-boot-starter
导入了一个包spring-boot-autoconfigure
。包里面都是各种场景的AutoConfiguration
自动配置类。 -
虽然全场景的自动配置都在
spring-boot-autoconfigure
这个包,但是不是全都开启的。 -
导入哪个场景就开启哪个自动配置。
实现原理与关键组件
-
@EnableAutoConfiguration
注解SpringBoot 应用主类上的
@SpringBootApplication
注解包含@EnableAutoConfiguration
,触发自动配置流程。- 通过
AutoConfigurationImportSelector
类扫描并加载所有符合条件的自动配置类。
- 通过
-
spring.factories
文件-
自动配置类定义在
META-INF/spring.factories
文件中,键为org.springframework.boot.autoconfigure.EnableAutoConfiguration
。 -
示例:
# spring-boot-autoconfigure.jar 中的 spring.factories org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\ org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration
-
-
条件化注解(Conditional Annotations)
自动配置类通过条件注解控制是否生效,优先级从高到低如下:
条件注解 作用 @ConditionalOnClass
类路径中存在指定类时生效 @ConditionalOnMissingBean
容器中不存在指定 Bean 时生效(开发者可覆盖默认配置) @ConditionalOnProperty
配置文件中存在指定属性且匹配值时生效 @ConditionalOnWebApplication
应用类型为 Web 应用时生效 @ConditionalOnResource
类路径中存在指定资源文件时生效 代码示例:
@Configuration @ConditionalOnClass({DataSource.class, EmbeddedDatabaseType.class}) @EnableConfigurationProperties(DataSourceProperties.class) public class DataSourceAutoConfiguration {// 自动配置 DataSource }
自动配置的工作流程
-
启动阶段
SpringBoot 启动时,
AutoConfigurationImportSelector
读取所有spring.factories
中的自动配置类。 -
条件过滤
遍历所有配置类,通过条件注解过滤掉不满足条件的类(如缺少依赖类、Bean 已存在等)。
-
Bean 注册
将符合条件的配置类加载到 Spring 容器,生成对应的 Bean 定义。
-
属性绑定
通过
@EnableConfigurationProperties
将application.properties
或application.yml
中的属性绑定到配置类。
流程细节梳理
-
导入
starter-web
:导入了 web 开发场景。- 场景启动器导入了相关场景的所有依赖:
starter-json
、starter-tomcat
、springmvc
。 - 每个场景启动器都引入了一个
spring-boot-starter
,核心场景启动器。 - 核心场景启动器引入了
spring-boot-autoconfigure
包。 spring-boot-autoconfigure
里面囊括了所有场景的所有配置。- 只要这个包下的所有类都能生效,那么相当于 SpringBoot 官方写好的整合功能就生效了。
- SpringBoot 默认却扫描不到
spring-boot-autoconfigure
下写好的所有配置类。(这些配置类给我们做了整合操作),默认只扫描主程序所在的包。
- 场景启动器导入了相关场景的所有依赖:
-
主程序:
@SpringBootApplication
。-
@SpringBootApplication
由三个注解组成@SpringBootConfiguration
、@EnableAutoConfiguratio
、@ComponentScan
。 -
SpringBoot 默认只能扫描自己主程序所在的包及其下面的子包,扫描不到
spring-boot-autoconfigure
包中官方写好的配置类。 -
@EnableAutoConfiguration
:SpringBoot 开启自动配置的核心。-
是由
@Import(AutoConfigurationImportSelector.class)
提供功能:批量给容器中导入组件。 -
SpringBoot 启动会默认加载142个配置类。
-
这142个配置类来自于
spring-boot-autoconfigure
下META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
文件指定的。 -
项目启动的时候利用
@Import
批量导入组件机制把autoconfigure
包下的142xxxxAutoConfiguration
类导入进来(自动配置类)。
-
-
按需生效:
-
并不是这142个自动配置类都能生效。
-
每一个自动配置类,都有条件注解
@ConditionalOnxxx
,只有条件成立,才能生效 。
-
-
-
xxxxAutoConfiguration
自动配置类-
给容器中使用@Bean 放一堆组件。
-
每个自动配置类都可能有这个注解
@EnableConfigurationProperties(**ServerProperties**.class)
,用来把配置文件中配的指定前缀的属性值封装到xxxProperties
属性类中。 -
以 Tomcat 为例:把服务器的所有配置都是以
server
开头的。配置都封装到了属性类中。 -
给容器中放的所有组件的一些核心参数,都来自于
xxxProperties
。xxxProperties
都是和配置文件绑定。 -
只需要改配置文件的值,核心组件的底层参数都能修改。
-
-
写业务,全程无需关心各种整合(底层这些整合写好了,而且也生效了)。
总结
-
导入
starter
,就会导入autoconfigure
包。 -
autoconfigure
包里面有一个文件META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
,里面指定的所有启动要加载的自动配置类。 -
@EnableAutoConfiguration
会自动的把上面文件里面写的所有自动配置类都导入进来,xxxAutoConfiguration
是有条件注解进行按需加载。 -
xxxAutoConfiguration
给容器中导入一堆组件,组件都是从xxxProperties
中提取属性值。 -
xxxProperties
又是和配置文件进行了绑定。
**效果:**导入 starter
、修改配置文件,就能修改底层行为。
自动配置的调试与验证
-
查看生效的自动配置
启动时添加
--debug
参数,输出ConditionEvaluationReport
:java -jar your-app.jar --debug
- 报告中会显示:
Positive matches
(已启用的配置)Negative matches
(未启用的配置及原因)
- 报告中会显示:
-
手动排除自动配置
在
application.properties
中排除特定配置类:spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
自动配置的典型场景
- 数据库配置
- 条件:类路径中存在
DataSource
相关类(如 HikariCP、JDBC Driver)。 - 行为:自动创建
DataSource
Bean,并根据spring.datasource.*
属性配置连接池。
- 条件:类路径中存在
- Web MVC 配置
- 条件:类路径中存在
spring-webmvc
。 - 行为:自动配置
DispatcherServlet
、视图解析器、静态资源处理等。
- 条件:类路径中存在
- 缓存配置
- 条件:类路径中存在缓存实现(如 Redis、EhCache)。
- 行为:自动初始化缓存管理器。
自定义自动配置
-
编写自动配置类
@Configuration @ConditionalOnClass(MyService.class) // 当 MyService 存在时生效 @EnableConfigurationProperties(MyProperties.class) // 绑定属性 public class MyAutoConfiguration {@Bean@ConditionalOnMissingBean // 容器中无 MyService 时创建public MyService myService(MyProperties properties) {return new MyService(properties.getConfig());} }
-
注册配置类
在
src/main/resources/META-INF/spring.factories
中添加:org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.example.MyAutoConfiguration
自动配置的局限性
-
依赖冲突
不同 Starter 可能引入冲突的自动配置(如多个数据源配置),需通过
@Primary
或@Qualifier
解决。 -
过度配置
自动加载不必要的组件可能影响性能,需通过
exclude
显式排除。 -
版本兼容性
第三方 Starter 的自动配置可能与 SpringBoot 版本不兼容,需注意版本匹配。
总结
Spring Boot 的自动配置通过 条件化加载 + 约定优于配置 的机制,实现了极简的项目初始化。开发者只需:
- 通过 Starter 引入依赖。
- 按需覆盖默认配置(如定义自定义 Bean 或修改属性)。
- 理解自动配置原理以高效调试。
这种机制在简化开发的同时,保留了高度的灵活性,是 SpringBoot 的核心竞争力之一。
常用注解介绍
核心注解 @SpringBootApplication
@SpringBootApplication
是 SpringBoot 应用的核心注解,其本质是一个组合注解(由三个关键注解构成)。
三个组合注解
@SpringBootConfiguration
-
继承自
@Configuration
。 -
标识当前类为配置类(允许通过
@Bean
定义组件)。 -
示例:
@Bean public DataSource dataSource() {return new HikariDataSource(); }
@EnableAutoConfiguration
-
启用自动配置机制(核心价值所在)。
-
工作原理:
- 扫描
META-INF/spring.factories
文件 - 根据类路径依赖智能配置(如检测到
spring-boot-starter-web
自动配置 Tomcat)
- 扫描
-
条件判断注解示例:
@ConditionalOnClass(DataSource.class) @AutoConfigureAfter(DataSourceAutoConfiguration.class)
-
配置排除:
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@ComponentScan
- 默认扫描当前包及其子包
- 自动注册以下注解标记的组件:
@Component
,@Service
,@Controller
,@Repository
。
配置参数详解
参数名称 | 作用描述 | 示例值 |
---|---|---|
scanBasePackages | 自定义组件扫描路径 | {"com.pkg1", "com.pkg2"} |
exclude | 排除特定自动配置类 | SecurityAutoConfiguration.class |
proxyBeanMethods | 控制 @Bean 方法代理行为 | true (默认)/false |
最佳实践
- 项目结构规范:主类应置于根包顶层以保证扫描范围
- 配置覆盖策略:优先使用
application.properties
而非代码排除 - 调试技巧:启动时添加
--debug
参数查看自动配置报告
与传统 Spring 对比
特性 | SpringBoot | 传统 Spring |
---|---|---|
配置方式 | 自动 + 注解 | XML + 显式配置 |
依赖管理 | starter POM 统一管理 | 手动添加依赖 |
部署方式 | 内嵌容器直接运行 | 需要外置容器部署 |
这个注解体现了 Spring Boot 的核心理念:约定大于配置,通过智能默认值大幅减少开发者的配置工作量。理解其底层机制有助于在需要深度定制时做出正确决策。
条件注解
条件注解(Conditional Annotations)是 SpringBoot 实现自动配置的核心机制,通过预定义条件控制 Bean 的创建与加载。其本质是基于 @Conditional
元注解扩展的派生注解,仅在满足特定条件时才会生效。注解格式是 @ConditionalOnXxx
。
常用注解及场景
以下为常见的条件注解及其典型用法:
注解名称 | 触发条件 | 使用场景示例 |
---|---|---|
@ConditionalOnClass | 类路径中存在指定类时生效 | 自动配置 DataSource 时检查驱动类是否存在 |
@ConditionalOnMissingBean | 容器中不存在指定 Bean 时生效 | 避免覆盖用户自定义的 Bean |
@ConditionalOnProperty | 配置文件中存在指定属性且匹配值时生效 | 根据 spring.datasource.enabled 开关配置 |
@ConditionalOnWebApplication | 当前应用是 Web 应用时生效 | 仅 Web 环境下注册特定的过滤器 |
@ConditionalOnExpression | SpEL 表达式结果为 true 时生效 | 复杂条件组合判断 |
底层实现原理
SpringBoot 通过 Condition
接口实现条件判断:
public interface Condition {boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}
ConditionContext
:提供环境变量、类加载器等上下文信息。AnnotatedTypeMetadata
:读取注解元数据。
开发实战示例
- 类存在时自动配置
@Configuration
@ConditionalOnClass(DataSource.class)
public class DataSourceAutoConfiguration {// 当类路径存在DataSource时自动配置
}
- 组合条件控制
@Bean
@ConditionalOnProperty(name = "cache.enabled", havingValue = "true")
@ConditionalOnMissingBean
public CacheService cacheService() {// 当配置cache.enabled=true且容器无CacheService时创建
}
-
自定义条件注解
- 实现
Condition
接口:
public class EnvCondition implements Condition {@Overridepublic boolean matches(...) {return context.getEnvironment().acceptsProfiles("prod");} }
- 定义注解:
@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Conditional(EnvCondition.class) public @interface ConditionalOnProduction {}
- 实现
调试技巧
- 启动时添加
--debug
参数查看匹配结果:
============================
CONDITIONS EVALUATION REPORT
============================
Positive matches:DataSourceAutoConfiguration matched:- @ConditionalOnClass found required class 'javax.sql.DataSource'
最佳实践建议
- 避免条件冲突:多个条件注解组合使用时注意逻辑完整性。
- 谨慎覆盖默认配置:优先使用
@ConditionalOnMissingBean
而非直接覆盖。 - 合理排序配置类:使用
@AutoConfigureOrder
控制配置加载顺序。
典型应用场景
- 多环境配置切换(dev、test、prod)。
- 模块化功能开关控制。
- 第三方库的自动适配。
- 兼容性处理(如不同版本 JDK 的适配)。
属性绑定注解
核心注解 @ConfigurationProperties
-
作用:将外部配置文件(如
application.yml
、application.properties
)中的属性批量绑定到 Java Bean。 -
使用场景:需要注入多个关联属性或层级化配置时。
-
特点:
- 类型安全:自动将属性值转换为 Java 类型(如
String
→Integer
)。 - 松散绑定:支持属性名多种格式(如
kebab-case
→camelCase
)。 - 嵌套对象支持:通过层级结构绑定复杂对象。
- 类型安全:自动将属性值转换为 Java 类型(如
-
示例:
@Component @ConfigurationProperties(prefix = "app") public class AppConfig {private String name;private List<String> servers;private Database database;// Getter/Setter 省略 }public class Database {private String url;private String username; }
# application.properties app.name=MyApp app.servers=server1,server2 app.database.url=jdbc:mysql://localhost:3306/db app.database.username=root
@EnableConfigurationProperties
启用属性绑定的开关。
-
核心作用:
-
注册配置类:将
@ConfigurationProperties
标注的类显式注册为 Spring Bean。 -
触发绑定流程:启用属性绑定机制,使
@ConfigurationProperties
生效。
-
-
使用场景:
-
非自动扫描的类:当配置类未被
@Component
扫描时(如第三方库中的类),需通过此注解手动注册。 -
明确控制配置类的加载顺序:在特定配置类中集中管理属性绑定。
-
-
示例
@Configuration @EnableConfigurationProperties(AppConfig.class) public class MyConfiguration {// 其他 Bean 定义 }
或直接标注在启动类:
@SpringBootApplication @EnableConfigurationProperties(AppConfig.class) public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);} }
-
关键特性
-
按需加载:仅在需要时启用特定配置类的绑定。
-
避免组件扫描依赖:不依赖
@ComponentScan
自动发现配置类。
-
逐项注入 @Value
-
作用:直接注入单个属性值到字段。
-
适用场景:需要注入少量独立属性时。
-
局限性:
- 不支持复杂类型(如嵌套对象)。
- 缺乏类型安全校验。
-
示例:
@Component public class MyService {@Value("${app.name}")private String appName; }
配置源扩展 @PropertySource
-
作用:加载自定义配置文件(非
application.*
)。 -
限制:默认仅支持
.properties
文件,需额外处理.yml
。 -
示例:
@Configuration @PropertySource("classpath:custom.properties") public class CustomConfig {// 使用 @Value 或 @ConfigurationProperties 绑定属性 }
yaml 格式配置文件
SpringBoot 的默认配置文件是 application.properties
,这种文件格式有一个问题:配置多以后难阅读和修改,层级结构辨识度不高。可以使用 yaml 格式的配置文件来解决这个问题。
yaml 格式概述
yaml 不是一种标记语言,设计目的就是为了方便人们读写,后缀名为:.yml
或 .yaml
。
与 .properties
对比优势:
- 层级结构更清晰。
- 支持复杂数据结构支持复杂数据结构。
- 减少重复配置减少重复配置。
核心语法规则
- 缩进表示层级(使用空格,不要用 Tab 键,一般为2空格)
- 键值对使用冒号 + 空格:
key: value
,:
和value
之间必须有一个空格。 - 列表使用短横线 + 空格:
servers:- dev.example.com- test.example.com
- 对象嵌套:
database:host: localhostport: 3306
语法格式
- 对象嵌套
person:name: 张三address:province: 浙江city: 杭州street: 西湖大道education:- 小学: 西湖实验小学- 中学: 杭州二中
- 集合类型:有两种表示方法。
- 行内列表:
fruits: [苹果, 香蕉, 橙子]
- 多行列表:每条数据格式为
- value
中间有一个空格。
fruits:- 苹果- 香蕉- 橙子
- Map映射
- 基础Map:
http_codes:200: OK404: Not Found500: Internal Server Error
- 复杂Map:
employees:emp001:name: 李四department: 研发部emp002:name: 王五department: 市场部
示例
@Component
@ConfigurationProperties(prefix = "person") //和配置文件person前缀的所有配置进行绑定
@Data //自动生成JavaBean属性的getter/setter
//@NoArgsConstructor //自动生成无参构造器
//@AllArgsConstructor //自动生成全参构造器
public class Person {private String name;private Integer age;private Date birthDay;private Boolean like;private Child child; //嵌套对象private List<Dog> dogs; //数组(里面是对象)private Map<String,Cat> cats; //表示Map
}@Data
public class Dog {private String name;private Integer age;
}@Data
public class Child {private String name;private Integer age;private Date birthDay;private List<String> text; //数组
}@Data
public class Cat {private String name;private Integer age;
}
person:name: 张三age: 18birthDay: 2010/10/10 12:12:12like: truechild:name: 李四age: 20birthDay: 2018/10/10text: ["abc","def"]dogs:- name: 小黑age: 3- name: 小白age: 2cats:c1:name: 小蓝age: 3c2: {name: 小绿,age: 2} #对象也可用{}表示
细节
-
birthDay
推荐写为birth-day
。 -
文本:
-
单引号不会转义(
\n
则为普通字符串显示) -
双引号会转义(
\n
会显示为换行符)
-
-
大文本:
-
|
开头,大文本写在下层,保留文本格式,换行符正确显示。 -
>
开头,大文本写在下层,折叠换行符。
-
-
多文档合并:
- 使用
---
可以把多个 yaml 文档合并在一个文档中,每个文档区依然认为内容独立。
- 使用
SpringBoot 特有语法规则
- 多环境配置示例:
spring:profiles:active: dev
---
spring:profiles: dev
server:port: 8080
---
spring:profiles: prod
server:port: 80
便于多个环境灵活切换。
日志配置
规范:项目开发不要编写 System.out.println()
,应该用日志记录信息。
SpringBoot 有一套默认的日志体系:
- 采用
Logback
作为默认实现(需排除spring-boot-starter-logging
才能切换)。 - 兼容
SLF4
J 门面接口。 - 支持
Log4j2
(需引入spring-boot-starter-log4j2
)。
SpringBoot 是如何配置日志的
- 每个
starter
场景,都会导入一个核心场景spring-boot-starter
。 - 核心场景引入了日志的所用功能
spring-boot-starter-logging
。 - 默认使用了
logback + slf4j
组合作为默认底层日志。 - 日志是系统一启动就要用,
xxxAutoConfiguration
是系统启动好了以后放好的组件,后来用的。 - 日志是利用监听器机制配置好的。
ApplicationListener
。 - 日志所有的配置都可以通过修改配置文件实现。以
logging
开始的所有配置。
示例:
- 使用
LoggerFactory.getLogger(类对象)
@RestController
public class HelloController {Logger log = LoggerFactory.getLogger(HelloController.class);@GetMapping("/hello")public String hello(){log.info("日志——方法进来了");return "hello SpringBoot";}}
- 使用注解
@Slf4j
@RestController
@Slf4j
public class HelloController {@GetMapping("/hello")public String hello(){log.info("日志——方法进来了");return "hello SpringBoot";}}
日志格式
默认输出格式:
- 时间和日期:毫秒级精度。
- 日志级别:
ERROR
,WARN
,INFO
,DEBUG
orTRACE
。 - 进程 ID。
---
: 消息分割符。- 线程名: 使用
[]
包含。 Logger
名: 通常是产生日志的类名。- 消息: 日志记录的内容。
注意: logback
没有 FATAL
级别,对应的是 ERROR
。
日志级别
-
由低到高:
ALL
,TRACE
,DEBUG
,INFO
,WARN
,ERROR
,FATAL
,OFF
。 -
只会打印指定级别及以上级别的日志。
-
ALL
:打印所有日志。 -
TRACE
:追踪框架详细流程日志,一般不使用。 -
DEBUG
:开发调试细节日志。 -
INFO
:关键、感兴趣信息日志。 -
WARN
:警告但不是错误的信息日志,比如:版本过时。 -
ERROR
:业务错误日志,比如出现各种异常。 -
FATAL
:致命错误日志,比如 jvm 系统崩溃。 -
OFF
:关闭所有日志记录。
-
-
不指定级别的所有类,都使用 root 指定的级别作为默认级别。
-
SpringBoot 日志默认级别是 INFO。
配置示例:
logging:level:root: INFO # 全局日志级别org.springframework: WARNcom.example: DEBUG # 包级日志控制file:name: app.log # 日志文件名(优先于path)path: /var/log # 日志目录(自动生成spring.log)pattern:console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"file: "%d{ISO8601} [%15.15t] %-5level %40.40logger{39} : %message%n"
日志分组
将相关的 logger
分组在一起,统一配置。SpringBoot 也支持。比如:Tomcat 相关的日志统一设置
logging.group.tomcat=org.apache.catalina,org.apache.coyote,org.apache.tomcat
logging.level.tomcat=trace
SpringBoot 默认有两个组
组名 | 成员 |
---|---|
web | org.springframework.core.codec ,org.springframework.http ,org.springframework.web ,org.springframework.boot.actuate.endpoint.web ,org.springframework.boot.web.servlet.ServletContextInitializerBeans |
sql | org.springframework.jdbc.core ,org.hibernate.SQL ,org.jooq.tools.LoggerListener |
日志输出
将日志输出成一个文件:
# 指定文件路径
logging.file.path=
# 指定文件名字
logging.file.name=a.log
如果没有指定文件路径则默认为项目目录。
也可以只在指定文件名字写日志文件的全路径名。
logging.file.name=D:\\a.log
归档与切割
归档:每天的日志单独存到一个文档中。
切割:每个文件10MB,超过大小切割成另外一个文件。
- 每天的日志应该独立分割出来存档。如果使用 logback(SpringBoot 默认整合),可以通过
application.properties
文件指定日志滚动规则。 - 如果是其他日志系统,需要自行配置(添加
log4j2.xml
或log4j2-spring.xml
) - 支持的滚动规则设置如下:
配置项 | 描述 |
---|---|
logging.logback.rollingpolicy.file-name-pattern | 日志存档的文件名格式(默认值:${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz ) |
logging.logback.rollingpolicy.clean-history-on-start | 应用启动时是否清除以前存档(默认值:false)。 |
logging.logback.rollingpolicy.max-file-size | 存档前,每个日志文件的最大大小(默认值:10MB)。 |
logging.logback.rollingpolicy.total-size-cap | 日志文件被删除之前,可以容纳的最大大小(默认值:0B)。设置1GB则磁盘存储超过 1GB 日志后就会删除旧日志文件。 |
logging.logback.rollingpolicy.max-history | 日志文件保存的最大天数(默认值:7)。 |
Web 开发
静态资源管理
-
默认静态资源路径
SpringBoot自动映射以下目录的静态资源:
classpath:/static/
classpath:/public/
例如:src/main/resources/static/js/main.js
可通过http://localhost:8080/js/main.js
访问2。
-
自定义资源路径与缓存控制
spring.web.resources.static-locations=classpath:/custom-static/ spring.web.resources.cache.period=3600 # 缓存1小时
控制器与请求处理
-
定义控制器
@RestController // 或 @Controller(需配合模板引擎) public class UserController {@GetMapping("/hello")public String hello() {return "Hello, Spring Boot!";} }
-
Restful风格API
@GetMapping("/user/{id}") public User getUser(@PathVariable Long id) {return userService.findById(id); }@PostMapping("/user") public User createUser(@RequestBody User user) {return userService.save(user); }
-
参数绑定注解
@RequestParam
:获取 URL 参数。@RequestBody
:解析 JSON 请求体。@ModelAttribute
:绑定表单数据。
高级功能
-
异常统一处理
@ControllerAdvice public class GlobalExceptionHandler {@ExceptionHandler(Exception.class)public ResponseEntity<String> handleException(Exception e) {return ResponseEntity.status(500).body("服务器错误: " + e.getMessage());} }
-
拦截器实现权限验证
public class AuthInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {if (request.getSession().getAttribute("user") == null) {response.sendRedirect("/login");return false;}return true;} }
注册拦截器:
@Configuration public class WebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new AuthInterceptor()).addPathPatterns("/admin/**");} }
SpringBoot 整合 SSM
- 导入依赖:
<dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.8</version>
</dependency>
- 配置数据源
application.yml
:
spring:datasource:url: jdbc:mysql://localhost:3306/test_db?useSSL=falseusername: rootpassword: 123456type: com.alibaba.druid.pool.DruidDataSourcemybatis:mapper-locations: classpath:mapper/*.xmlconfiguration:map-underscore-to-camel-case: true
- 实体类与
Mapper
接口
实体类:
public class User {private Integer id;private String username;// getters/setters
}
Mapper
接口:
@Mapper
public interface UserMapper {@Select("SELECT * FROM user WHERE id = #{id}")User selectById(Integer id);
}
Service
层实现:
@Service
public class UserServiceImpl implements UserService {@Autowiredprivate UserMapper userMapper;@Transactionalpublic User getUserById(Integer id) {return userMapper.selectById(id);}
}
Controller
层
@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;@GetMapping("/{id}")public User get(@PathVariable Integer id) {return userService.getUserById(id);}
}
- 事务配置
在主启动类添加注解:
@SpringBootApplication
@EnableTransactionManagement
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}
关键优化点
- 使用
@MapperScan("com.yigongsui.mapper")
替代单个@Mapper
注解。 - 多数据源需配置
@Primary
注解。 MyBatis
分页插件整合:
@Configuration
public class MyBatisConfig {@Beanpublic PaginationInterceptor paginationInterceptor() {return new PaginationInterceptor();}
}
Profile 环境配置
核心功能
Profile 是 SpringBoot 用于区分多环境配置的核心机制,通过激活不同的 Profile 可加载对应环境的配置。例如:
- 开发环境:
application-dev.yml
- 测试环境:
application-test.yml
- 生产环境:
application-prod.yml
使用方法
命名规则
配置文件名需遵循 application-{profile}.properties
或 application-{profile}.yml
格式,例如 application-dev.yml
。
激活方式
- 配置文件激活:在主配置文件中设置
spring.profiles.active=dev
- 命令行激活:
java -jar app.jar --spring.profiles.active=dev,test
(支持多 Profile) - 环境变量激活:
export SPRING_PROFILES_ACTIVE=prod
多 Profile 共存
- 通用配置写在
application.yml
中 - 环境特有配置写在
application-{profile}.yml
中 - 优先级:Profile 专属配置 > 通用配置
外部配置加载顺序与优先级规则
SpringBoot 按从高到低的优先级加载配置,高优先级配置会覆盖低优先级的同名属性,非冲突配置会互补共存:
配置来源 | 路径示例 | 优先级 |
---|---|---|
命令行参数 | --server.port=8080 | 最高 |
外部目录配置文件 | file:../config/application.yml | 1 |
项目根目录配置文件 | file:./application.yml | 2 |
classpath 配置目录 | classpath:/config/application.yml | 3 |
classpath 根目录 | classpath:/application.yml | 最低 |
Nacos 远程配置 | 通过 spring.cloud.nacos.config 指定 | 覆盖本地配置 |
特殊规则说明
-
同目录文件优先级
若同一路径存在
.properties
和.yml
文件,优先加载.properties
-
Profile 配置文件加载顺序
- 加载主配置文件(如
application.yml
) - 加载激活的 Profile 文件(如
application-dev.yml
) - 远程配置中心配置最后加载。
- 加载主配置文件(如
-
覆盖逻辑示例
- 若
application.yml
中定义server.port=8080
application-dev.yml
中定义server.port=9090
- 最终生效端口为 9090。
- 若
SpringBoot 生命周期
生命周期机制介绍
SpringBoot 应用的生命周期由 Spring 框架的 ApplicationContext
和 Bean
生命周期机制驱动,分为以下核心阶段:
- 应用启动阶段
- 初始化
SpringApplication
,加载配置文件和环境变量。 - 触发
ApplicationStartingEvent
事件。 - 创建
ApplicationContext
,加载 Bean 定义。 - 执行
CommandLineRunner
或ApplicationRunner
接口实现类的逻辑。
- 初始化
- Bean 生命周期阶段
- 实例化:通过构造函数或工厂方法创建 Bean。
- 依赖注入:通过
@Autowired
或 XML 配置注入依赖。 - 初始化:通过
@PostConstruct
注解或实现InitializingBean
接口执行初始化逻辑。 - 销毁:通过
@PreDestroy
注解或实现DisposableBean
接口执行销毁逻辑。
- 应用关闭阶段
- 触发
ContextClosedEvent
事件。 - 销毁所有单例 Bean。
- 关闭
ApplicationContext
。
- 触发
使用方法
-
自定义 Bean 生命周期方法
使用注解定义初始化和销毁逻辑:
@Component public class MyService {@PostConstructpublic void init() {System.out.println("Bean 初始化完成");}@PreDestroypublic void cleanup() {System.out.println("Bean 销毁前清理");} }
-
监听应用生命周期事件
实现
ApplicationListener
接口监听事件:@Component public class MyListener implements ApplicationListener<ApplicationReadyEvent> {@Overridepublic void onApplicationEvent(ApplicationReadyEvent event) {System.out.println("应用启动完成");} }
-
使用 Actuator 监控生命周期状态
通过
/actuator/health
端点监控应用健康状态3:# application.yml management:endpoints:web:exposure:include: health,info
性能优化建议
- 避免在
@PostConstruct
中执行耗时操作。 - 使用
SmartLifecycle
接口控制 Bean 启动顺序。 - 结合 Actuator 的
/actuator/shutdown
端点实现优雅停机。
Swagger
Swagger 是一套用于设计、构建和记录 RESTful API 的开源工具,基于 OpenAPI 规范。它支持自动生成交互式 API 文档,并提供可视化界面用于接口测试。在 SpringBoot 中,Swagger 的集成主要通过依赖库(如 springdoc-openapi
)实现。
SpringBoot 集成 Swagger 的步骤
-
添加依赖
在
pom.xml
中添加以下依赖(注意:SpringBoot 3.x 需使用springdoc-openapi
,而非旧版springfox
):<dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId><version>2.3.0</version> <!-- 确保版本兼容 --> </dependency>
-
配置 Swagger
在
application.yml
中配置基础信息:springdoc:swagger-ui:path: /swagger-ui.html # 访问路径tags-sorter: alpha # 标签排序规则api-docs:path: /v3/api-docs # OpenAPI 描述文件路径info:title: API 文档version: 1.0.0description: Swagger 示例
-
添加注解
在
Controller
类和方法上使用注解描述接口:@RestController @OpenAPIDefinition(info = @Info(title = "用户管理接口")) public class UserController {@Operation(summary = "获取用户列表", description = "分页查询用户")@GetMapping("/users")public List<User> getUsers() {// 业务逻辑} }
-
访问文档界面
启动应用后,通过以下 URL 访问 Swagger UI:
http://localhost:端口/swagger-ui.html
关键注解说明
注解 | 用途 |
---|---|
@OpenAPIDefinition | 定义全局 API 信息 |
@Operation | 描述单个接口功能 |
@Parameter | 定义接口参数 |
@Tag | 对接口分组(替代旧版 @Api ) |
注意事项
- 兼容性:SpringBoot 3.x 需使用
springdoc-openapi
,旧版springfox
不再支持。 - 安全性:生产环境需通过权限控制 Swagger 访问,避免暴露敏感信息。
- 配置简化:若无需自定义配置,依赖添加后即可自动生成文档。
SpringBoot 远程调用
基于 HTTP 的远程调用
WebClient(响应式非阻塞)
适用于异步场景,需引入 spring-boot-starter-webflux
依赖:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
示例:
// 创建 WebClient 实例
WebClient client = WebClient.create("http://api.example.com");// 发起 GET 请求
Mono<String> response = client.get().uri("/data").retrieve().bodyToMono(String.class);// 处理响应(异步)
response.subscribe(result -> System.out.println("响应结果: " + result));
RestTemplate(同步阻塞)
传统同步方式,需注意在 SpringBoot 3.x 中未完全弃用但推荐使用 WebClient
:
@Bean
public RestTemplate restTemplate() {return new RestTemplate();
}// 调用示例
String result = restTemplate.getForObject("http://api.example.com/data", String.class);
声明式 HTTP 客户端(OpenFeign)
通过接口注解简化调用,需整合 SpringCloud OpenFeign。
步骤:
-
添加依赖:
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
-
启用 Feign 客户端(使用注解
@EnableFeignClients
):@SpringBootApplication @EnableFeignClients public class Application { ... }
-
定义接口:
@FeignClient(name = "example-service", url = "http://api.example.com") public interface ExampleClient {@GetMapping("/data")String getData(); }
-
注入使用:
@Autowired private ExampleClient exampleClient;public void callRemote() {String data = exampleClient.getData(); }
RPC 框架(如 gRPC)
适用于高性能二进制通信,需额外配置协议文件和服务端/客户端实现。
实现步骤:
- 添加
grpc-spring-boot-starter
依赖。 - 定义
.proto
文件描述服务接口。 - 生成 Java 代码并实现服务逻辑。
注意事项
- 版本兼容性:SpringBoot 3.x 需搭配 SpringCloud 2022.x 及以上版本。
- 性能优化:异步场景优先选择
WebClient
,同步场景可使用RestTemplate
。 - 异常处理:需捕获
WebClientResponseException
或FeignException
等特定异常。
SpringSecurity
SpringSecurity 是 Spring 生态中专注于安全管理的框架,提供身份验证(Authentication)、授权(Authorization)、会话管理等核心功能,通过声明式配置简化安全控制逻辑。
核心功能
- 身份验证:验证用户身份(如用户名密码、OAuth2)。
- 授权:控制用户对资源的访问权限(如角色/权限校验)。
- 会话管理:管理用户会话生命周期与安全性。
- 安全防护:防御 CSRF、XSS、SQL 注入等攻击。
SpringBoot 集成 SpringSecurity
- 导入依赖:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency>
- 配置基础安全规则
创建 SecurityConfig
类,配置默认安全策略:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;@Configuration
public class SecurityConfig {@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(auth -> auth.requestMatchers("/public/**").permitAll() // 公开路径.anyRequest().authenticated() // 其他路径需认证).formLogin(form -> form.loginPage("/login") // 自定义登录页.permitAll()).logout(logout -> logout.permitAll());return http.build();}
}
- 自定义用户服务(内存示例)
import org.springframework.context.annotation.Bean;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;@Bean
public UserDetailsService userDetailsService() {InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();manager.createUser(User.withUsername("admin").password("{noop}admin123") // {noop} 表示明文密码(仅测试用).roles("ADMIN").build());return manager;
}
- 启动并测试
运行项目后,访问受保护接口(如 /home
)将自动跳转到默认登录页,使用配置的用户名密码登录。
进阶配置
-
基于注解的权限控制
使用
@PreAuthorize
实现方法级权限校验:@GetMapping("/admin") @PreAuthorize("hasRole('ADMIN')") public String adminPage() {return "Admin Panel"; }
-
密码加密配置
推荐使用
BCryptPasswordEncoder
:@Bean public PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder(); }
-
动态权限管理
通过实现
UserDetailsService
和自定义权限逻辑,从数据库加载用户权限。
总结
SpringSecurity 通过声明式配置简化安全逻辑,SpringBoot 通过自动配置进一步降低集成成本。实际项目中需结合数据库、加密算法和动态权限管理实现完整方案。