什么是 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 配置,通过注解和默认配置简化开发。
- 起步依赖统一管理版本,避免冲突。
- 内嵌服务器实现"一键启动"。
核心组件
- 启动流程
java
@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 项目)。
xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.4.4</version>
</parent>
- 导入 SpringBoot Web 依赖:
xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
这个依赖不需要指定版本号。
- 创建 SpringBoot 主程序:
java
@SpringBootApplication
public class MainApplication {
public static void main(String[] args) {
SpringApplication.run(MainApplication.class, args);
}
}
要在类上添加注解 @SpringBootApplication
。
- 在主程序所在包下创建
controller
层:
java
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello(){
return "Hello SpringBoot";
}
}
- 启动项目,访问
localhost:8080/hello
进行测试,出现hello SpringBoot
成功。
如果想要打成 jar 包,需要在 pom.xml
导入插件依赖:
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
<?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>
主程序:
java
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>
:开发者信息:- 支持多开发者声明。
- 包含开发者身份识别和联系方式。
xml<developers> <developer> <id>dev001</id> <name>张三</name> <email>[email protected]</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。
核心原理
-
依赖传递逻辑
xml<!-- 引入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
-
自动配置流程
java@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 // 注册自动配置
-
实现自动配置类
java@Configuration @EnableConfigurationProperties(MyServiceProperties.class) @ConditionalOnClass(MyService.class) public class MyServiceAutoConfiguration { @Bean @ConditionalOnMissingBean public MyService myService(MyServiceProperties properties) { return new MyService(properties.getConfig()); } }
-
配置属性绑定
java@ConfigurationProperties(prefix = "my.service") public class MyServiceProperties { private String config = "default"; // getters & setters }
-
注册自动配置
spring.factories
内容:factoriesorg.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),预定义了所有官方支持的依赖版本 -
开发者无需手动指定依赖版本号,例如:
xml<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
(推荐,就是快速开始的第一个项目)
xml
<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(非继承场景)
xml
<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>
版本覆盖机制
当需要自定义依赖版本时:
xml
<properties>
<mysql.version>8.0.33</mysql.version> <!-- 覆盖Spring Boot默认的MySQL驱动版本 -->
</properties>
- 优先级:项目指定版本 > BOM版本
- 风险提示:覆盖版本可能导致兼容性问题
依赖排除技术
处理冲突依赖的典型场景,例如 Web 模块排除 Tomcat:
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>
- 此时可手动添加其他 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:
java
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
。
会自动扫描主程序所在的包及其下面的子包。
也可以自定义扫描路径:
java
@SpringBootApplication(scanBasePackages = {"",""})
或
@ComponentScan({"",""})
默认配置值
SpringBoot 还编写了大量的默认配置属性,例如 Tomcat 启动的端口号是 8080。
-
配置文件 的所有配置项是和某个类的对象值进行一一绑定的。
-
绑定了配置文件中每一项值的类: 属性类。
-
比如:
-
ServerProperties
绑定了所有 Tomcat 服务器有关的配置。 -
MultipartProperties
绑定了所有文件上传相关的配置。
-
如果想要修改默认值,在 SpringBoot 的资源文件 application.properties
下编写:
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
。 -
示例:
Properties# 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
类路径中存在指定资源文件时生效 代码示例:
java@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
:bashjava -jar your-app.jar --debug
- 报告中会显示:
Positive matches
(已启用的配置)Negative matches
(未启用的配置及原因)
- 报告中会显示:
-
手动排除自动配置
在
application.properties
中排除特定配置类:propertiesspring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
自动配置的典型场景
- 数据库配置
- 条件 :类路径中存在
DataSource
相关类(如 HikariCP、JDBC Driver)。 - 行为 :自动创建
DataSource
Bean,并根据spring.datasource.*
属性配置连接池。
- 条件 :类路径中存在
- Web MVC 配置
- 条件 :类路径中存在
spring-webmvc
。 - 行为 :自动配置
DispatcherServlet
、视图解析器、静态资源处理等。
- 条件 :类路径中存在
- 缓存配置
- 条件:类路径中存在缓存实现(如 Redis、EhCache)。
- 行为:自动初始化缓存管理器。
自定义自动配置
-
编写自动配置类
java@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
中添加:propertiesorg.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.example.MyAutoConfiguration
自动配置的局限性
-
依赖冲突
不同 Starter 可能引入冲突的自动配置(如多个数据源配置),需通过
@Primary
或@Qualifier
解决。 -
过度配置
自动加载不必要的组件可能影响性能,需通过
exclude
显式排除。 -
版本兼容性
第三方 Starter 的自动配置可能与 SpringBoot 版本不兼容,需注意版本匹配。
总结
Spring Boot 的自动配置通过 条件化加载 + 约定优于配置 的机制,实现了极简的项目初始化。开发者只需:
- 通过 Starter 引入依赖。
- 按需覆盖默认配置(如定义自定义 Bean 或修改属性)。
- 理解自动配置原理以高效调试。
这种机制在简化开发的同时,保留了高度的灵活性,是 SpringBoot 的核心竞争力之一。
常用注解介绍
核心注解 @SpringBootApplication
@SpringBootApplication
是 SpringBoot 应用的核心注解,其本质是一个组合注解(由三个关键注解构成)。
三个组合注解
@SpringBootConfiguration
-
继承自
@Configuration
。 -
标识当前类为配置类(允许通过
@Bean
定义组件)。 -
示例:
java@Bean public DataSource dataSource() { return new HikariDataSource(); }
@EnableAutoConfiguration
-
启用自动配置机制(核心价值所在)。
-
工作原理:
- 扫描
META-INF/spring.factories
文件 - 根据类路径依赖智能配置(如检测到
spring-boot-starter-web
自动配置 Tomcat)
- 扫描
-
条件判断注解示例:
java@ConditionalOnClass(DataSource.class) @AutoConfigureAfter(DataSourceAutoConfiguration.class)
-
配置排除:
java@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
接口实现条件判断:
java
public interface Condition {
boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}
ConditionContext
:提供环境变量、类加载器等上下文信息。AnnotatedTypeMetadata
:读取注解元数据。
开发实战示例
- 类存在时自动配置
java
@Configuration
@ConditionalOnClass(DataSource.class)
public class DataSourceAutoConfiguration {
// 当类路径存在DataSource时自动配置
}
- 组合条件控制
java
@Bean
@ConditionalOnProperty(name = "cache.enabled", havingValue = "true")
@ConditionalOnMissingBean
public CacheService cacheService() {
// 当配置cache.enabled=true且容器无CacheService时创建
}
-
自定义条件注解
- 实现
Condition
接口:
javapublic class EnvCondition implements Condition { @Override public boolean matches(...) { return context.getEnvironment().acceptsProfiles("prod"); } }
- 定义注解:
java@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Conditional(EnvCondition.class) public @interface ConditionalOnProduction {}
- 实现
调试技巧
- 启动时添加
--debug
参数查看匹配结果:
java
============================
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 类型(如
-
示例:
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; }
properties# 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
扫描时(如第三方库中的类),需通过此注解手动注册。 -
明确控制配置类的加载顺序:在特定配置类中集中管理属性绑定。
-
-
示例
java@Configuration @EnableConfigurationProperties(AppConfig.class) public class MyConfiguration { // 其他 Bean 定义 }
或直接标注在启动类:
java@SpringBootApplication @EnableConfigurationProperties(AppConfig.class) public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
-
关键特性
-
按需加载:仅在需要时启用特定配置类的绑定。
-
避免组件扫描依赖 :不依赖
@ComponentScan
自动发现配置类。
-
逐项注入 @Value
-
作用 :直接注入单个属性值到字段。
-
适用场景:需要注入少量独立属性时。
-
局限性:
- 不支持复杂类型(如嵌套对象)。
- 缺乏类型安全校验。
-
示例:
java@Component public class MyService { @Value("${app.name}") private String appName; }
配置源扩展 @PropertySource
-
作用 :加载自定义配置文件 (非
application.*
)。 -
限制 :默认仅支持
.properties
文件,需额外处理.yml
。 -
示例:
java@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
之间必须有一个空格。 - 列表使用短横线 + 空格:
yaml
servers:
- dev.example.com
- test.example.com
- 对象嵌套:
yaml
database:
host: localhost
port: 3306
语法格式
- 对象嵌套
yaml
person:
name: 张三
address:
province: 浙江
city: 杭州
street: 西湖大道
education:
- 小学: 西湖实验小学
- 中学: 杭州二中
- 集合类型:有两种表示方法。
- 行内列表:
yaml
fruits: [苹果, 香蕉, 橙子]
- 多行列表:每条数据格式为
- value
中间有一个空格。
yaml
fruits:
- 苹果
- 香蕉
- 橙子
- Map映射
- 基础Map:
yaml
http_codes:
200: OK
404: Not Found
500: Internal Server Error
- 复杂Map:
yaml
employees:
emp001:
name: 李四
department: 研发部
emp002:
name: 王五
department: 市场部
示例
java
@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;
}
yaml
person:
name: 张三
age: 18
birthDay: 2010/10/10 12:12:12
like: true
child:
name: 李四
age: 20
birthDay: 2018/10/10
text: ["abc","def"]
dogs:
- name: 小黑
age: 3
- name: 小白
age: 2
cats:
c1:
name: 小蓝
age: 3
c2: {name: 小绿,age: 2} #对象也可用{}表示
细节
-
birthDay
推荐写为birth-day
。 -
文本:
-
单引号 不会转义(
\n
则为普通字符串显示) -
双引号 会转义(
\n
会显示为换行符)
-
-
大文本:
-
|
开头,大文本写在下层,保留文本格式 ,换行符正确显示。 -
>
开头,大文本写在下层,折叠换行符。
-
-
多文档合并:
- 使用
---
可以把多个 yaml 文档合并在一个文档中,每个文档区依然认为内容独立。
- 使用
SpringBoot 特有语法规则
- 多环境配置示例:
yaml
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(类对象)
java
@RestController
public class HelloController {
Logger log = LoggerFactory.getLogger(HelloController.class);
@GetMapping("/hello")
public String hello(){
log.info("日志------方法进来了");
return "hello SpringBoot";
}
}
- 使用注解
@Slf4j
java
@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。
配置示例:
yaml
logging:
level:
root: INFO # 全局日志级别
org.springframework: WARN
com.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 相关的日志统一设置
properties
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 |
日志输出
将日志输出成一个文件:
properties
# 指定文件路径
logging.file.path=
# 指定文件名字
logging.file.name=a.log
如果没有指定文件路径则默认为项目目录。
也可以只在指定文件名字写日志文件的全路径名。
properties
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。
-
自定义资源路径与缓存控制
propertiesspring.web.resources.static-locations=classpath:/custom-static/ spring.web.resources.cache.period=3600 # 缓存1小时
控制器与请求处理
-
定义控制器
java@RestController // 或 @Controller(需配合模板引擎) public class UserController { @GetMapping("/hello") public String hello() { return "Hello, Spring Boot!"; } }
-
Restful风格API
java@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
:绑定表单数据。
高级功能
-
异常统一处理
java@ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) public ResponseEntity<String> handleException(Exception e) { return ResponseEntity.status(500).body("服务器错误: " + e.getMessage()); } }
-
拦截器实现权限验证
javapublic class AuthInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (request.getSession().getAttribute("user") == null) { response.sendRedirect("/login"); return false; } return true; } }
注册拦截器:
java@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new AuthInterceptor()).addPathPatterns("/admin/**"); } }
SpringBoot 整合 SSM
- 导入依赖:
xml
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.8</version>
</dependency>
- 配置数据源
application.yml
:
yaml
spring:
datasource:
url: jdbc:mysql://localhost:3306/test_db?useSSL=false
username: root
password: 123456
type: com.alibaba.druid.pool.DruidDataSource
mybatis:
mapper-locations: classpath:mapper/*.xml
configuration:
map-underscore-to-camel-case: true
- 实体类与
Mapper
接口
实体类:
java
public class User {
private Integer id;
private String username;
// getters/setters
}
Mapper
接口:
java
@Mapper
public interface UserMapper {
@Select("SELECT * FROM user WHERE id = #{id}")
User selectById(Integer id);
}
Service
层实现:
java
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Transactional
public User getUserById(Integer id) {
return userMapper.selectById(id);
}
}
Controller
层
java
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
public User get(@PathVariable Integer id) {
return userService.getUserById(id);
}
}
- 事务配置
在主启动类添加注解:
java
@SpringBootApplication
@EnableTransactionManagement
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
关键优化点
- 使用
@MapperScan("com.yigongsui.mapper")
替代单个@Mapper
注解。 - 多数据源需配置
@Primary
注解。 MyBatis
分页插件整合:
java
@Configuration
public class MyBatisConfig {
@Bean
public 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 生命周期方法
使用注解定义初始化和销毁逻辑:
java@Component public class MyService { @PostConstruct public void init() { System.out.println("Bean 初始化完成"); } @PreDestroy public void cleanup() { System.out.println("Bean 销毁前清理"); } }
-
监听应用生命周期事件
实现
ApplicationListener
接口监听事件:java@Component public class MyListener implements ApplicationListener<ApplicationReadyEvent> { @Override public void onApplicationEvent(ApplicationReadyEvent event) { System.out.println("应用启动完成"); } }
-
使用 Actuator 监控生命周期状态
通过
/actuator/health
端点监控应用健康状态3:yaml# 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
):xml<dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> <version>2.3.0</version> <!-- 确保版本兼容 --> </dependency>
-
配置 Swagger
在
application.yml
中配置基础信息:yamlspringdoc: swagger-ui: path: /swagger-ui.html # 访问路径 tags-sorter: alpha # 标签排序规则 api-docs: path: /v3/api-docs # OpenAPI 描述文件路径 info: title: API 文档 version: 1.0.0 description: Swagger 示例
-
添加注解
在
Controller
类和方法上使用注解描述接口:java@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
依赖:
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
示例:
java
// 创建 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
:
java
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
// 调用示例
String result = restTemplate.getForObject("http://api.example.com/data", String.class);
声明式 HTTP 客户端(OpenFeign)
通过接口注解简化调用,需整合 SpringCloud OpenFeign。
步骤:
-
添加依赖:
xml<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
-
启用 Feign 客户端(使用注解
@EnableFeignClients
):java@SpringBootApplication @EnableFeignClients public class Application { ... }
-
定义接口:
java@FeignClient(name = "example-service", url = "http://api.example.com") public interface ExampleClient { @GetMapping("/data") String getData(); }
-
注入使用:
java@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
- 导入依赖:
xml
<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
类,配置默认安全策略:
java
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 {
@Bean
public 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();
}
}
- 自定义用户服务(内存示例)
java
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
实现方法级权限校验:java@GetMapping("/admin") @PreAuthorize("hasRole('ADMIN')") public String adminPage() { return "Admin Panel"; }
-
密码加密配置
推荐使用
BCryptPasswordEncoder
:java@Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }
-
动态权限管理
通过实现
UserDetailsService
和自定义权限逻辑,从数据库加载用户权限。
总结
SpringSecurity 通过声明式配置简化安全逻辑,SpringBoot 通过自动配置进一步降低集成成本。实际项目中需结合数据库、加密算法和动态权限管理实现完整方案。