当前位置: 首页 > news >正文

SpringBoot 学习

什么是 SpringBoot

SpringBoot 是基于 Spring 生态的开源框架,旨在简化 Spring 应用的初始化搭建开发配置。它通过约定大于配置的理念,提供快速构建生产级应用的解决方案,显著降低开发者对 XML 配置和依赖管理的负担。

特点:

  • 快速创建独立 Spring 应用。

  • 直接嵌入 Tomcat、Jetty or Undertow(无需部署 war 包)(Servlet容器)。

  • 提供可选的 starter,简化应用整合。

  • 按需自动配置 Spring 以及第三方库。

  • 提供生产级特性:如 监控指标、健康检查、外部化配置等。

  • 无代码生成、无xml。

核心特性

  1. 自动配置
    • 原理:根据项目依赖的 JAR 包(如 spring-boot-starter-data-jpa),自动推断并配置所需的 Bean(如数据源、事务管理器等)。
    • 示例:引入 spring-boot-starter-web 后,自动配置内嵌 Tomcat、Spring MVC 和 Jackson 库。
    • 自定义:通过 application.properties@Configuration 类覆盖默认配置。
  2. 起步依赖
    • 作用:将功能相关的依赖打包成一组(如 spring-boot-starter-data-redis),解决版本冲突问题。
    • 本质:基于 Maven/Gradle 的依赖传递机制,简化 pom.xmlbuild.gradle 配置。
  3. 内嵌服务器
    • 支持服务器:Tomcat(默认)、Jetty、Undertow。
    • 优势:无需部署 WAR 包到外部服务器,直接通过 main() 方法运行 JAR 文件。
  4. 生产就绪功能
    • 集成 Spring Boot Actuator:提供监控端点(如 /health, /metrics),支持应用性能追踪和健康检查。
    • 外部化配置:支持多环境配置(如 application-dev.yml, application-prod.yml)。

为什么会出现 SpringBoot

  1. 传统 Spring 的痛点
    • 繁琐的 XML 配置和重复的注解配置。
    • 依赖版本冲突频繁,需手动协调。
    • 部署依赖外部服务器,开发效率低。
  2. Spring Boot 的优化
    • 零 XML 配置,通过注解和默认配置简化开发。
    • 起步依赖统一管理版本,避免冲突。
    • 内嵌服务器实现“一键启动”。

核心组件

  1. 启动流程
@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}
  • @SpringBootApplication 组合了三个注解:
    • @SpringBootConfiguration:标识为配置类。
    • @EnableAutoConfiguration:启用自动配置。
    • @ComponentScan:扫描当前包及子包的组件。
  • SpringApplication.run() 启动内嵌服务器,加载自动配置类。
  1. 条件装配(Conditional)

Spring Boot 通过 @ConditionalOnClass@ConditionalOnMissingBean 等注解,动态判断是否装配某个 Bean。例如:

  • 当类路径存在 DataSource.class 时,才自动配置数据源。
  • 当容器中无自定义的 DataSource Bean 时,使用默认配置。

应用场景

  1. 快速构建 RESTful API

    使用 @RestControllerspring-boot-starter-web,几分钟内完成 API 开发与测试。

  2. 微服务开发

    作为 Spring Cloud 微服务架构的基础,轻松整合服务注册(Eureka)、配置中心(Config)等功能。

  3. 批处理任务

    结合 spring-boot-starter-batch 实现定时任务或大数据处理。

  4. 数据驱动应用

    整合 JPA(spring-boot-starter-data-jpa)或 MyBatis,快速操作数据库。

SpringBoot 与 Spring 关系

对比项SpringSpring Boot
定位基础框架,提供 IOC、AOP、事务管理等核心功能Spring 的扩展,简化配置和开发流程
配置方式需手动配置 XML 或 Java Config约定大于配置,自动装配为主
依赖管理需开发者自行解决依赖冲突通过 Starter 管理依赖和版本
部署依赖外部服务器(如 Tomcat)内嵌服务器,打包为可执行 JAR

优缺点

  • 优点
    • 快速上手,适合新手和快速原型开发。
    • 生态丰富,与 Spring Cloud、Spring Security 无缝整合。
    • 社区活跃,文档完善。
  • 缺点
    • 过度依赖自动配置,可能隐藏底层细节(需理解原理以调试复杂问题)。
    • 大型项目可能需要自定义配置覆盖默认行为。

总结

简化开发,简化配置,简化整合,简化部署,简化监控,简化运维。

快速开始

场景:快速开发一个 SpringBoot Web 工程。

快速搭建一个 SpringBoot 项目有两种方式:

SpringBoot 3 要求的 jdk 最低版本为 17。

创建 Maven 项目,转成 SpringBoot 项目

步骤:

  1. 创建一个 Maven 项目。
  2. pom.xml 文件导入一个父工程(SpringBoot 项目)。
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.4.4</version>
</parent>
  1. 导入 SpringBoot Web 依赖:
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
</dependencies>

这个依赖不需要指定版本号

  1. 创建 SpringBoot 主程序:
@SpringBootApplication
public class MainApplication {public static void main(String[] args) {SpringApplication.run(MainApplication.class, args);}}

要在类上添加注解 @SpringBootApplication

  1. 在主程序所在包下创建 controller 层:
@RestController
public class HelloController {@GetMapping("/hello")public String hello(){return "Hello SpringBoot";}}
  1. 启动项目,访问 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 项目

  1. 使用初始化工具创建 SpringBoot 项目:

在这里插入图片描述

新版 idea 是 Spring Boot,老版是 Spring Initializr。

项目名自行取即可。

  1. 点 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 各标签信息(了解即可)

  1. <url>(根级别):项目基础信息。

    • 表示项目主页 URL。
    • 示例:<url>https://github.com/yourname/project</url>
    • 用于生成项目文档链接。
  2. <license>:许可证信息,需包含:

    • <name>:许可证名称(如 MIT License)。
    • <url>:许可证文本地址。
    • <distribution>:分发方式(通常为"repo")。
  3. <developers>:开发者信息:

    • 支持多开发者声明。
    • 包含开发者身份识别和联系方式。
    <developers><developer><id>dev001</id><name>张三</name><email>zhangsan@example.com</email><roles><role>架构师</role></roles></developer>
    </developers>
    
  4. <scm>:版本控制配置

    • connection:只读访问路径。
    • developerConnection:开发者提交权限路径。
    • 协议差异:
      • https:匿名只读访问。
      • ssh:需认证的读写访问。
    • <tag> 标记当前代码版本。

starter 概述

定义与作用

  1. 简化依赖管理

    SpringBoot starter 是预定义的依赖描述模板(pom.xmlbuild.gradle 片段),通过约定大于配置原则,将特定功能所需的多组依赖库整合为单一依赖项,核心原理是依赖传递。

    示例:引入 spring-boot-starter-web 会自动包含 Spring MVC、Tomcat、Jackson 等 Web 开发基础依赖。

  2. 自动配置机制

    每个 starter 包含一个 spring.factories 文件,声明了关联的自动配置类(如 WebMvcAutoConfiguration)。SpringBoot启动时通过 @EnableAutoConfiguration 扫描这些配置类,根据条件注解(如 @ConditionalOnClass)动态创建 Bean。

核心原理

  1. 依赖传递逻辑

    <!-- 引入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
  2. 自动配置流程

    @Configuration
    @ConditionalOnClass({ Servlet.class, DispatcherServlet.class })
    @AutoConfigureAfter(ServletWebServerFactoryAutoConfiguration.class)
    public class WebMvcAutoConfiguration {// 自动配置DispatcherServlet、视图解析器等组件
    }
    

常见 starter 分类

类型示例功能描述
官方标准 starterspring-boot-starter-data-jpa集成 JPA 与 Hibernate
技术整合 starterspring-boot-starter-security添加安全认证与授权功能
第三方 startermybatis-spring-boot-starterMyBatis orm 框架集成

自定义 Starter 开发步骤

  1. 创建模块结构

    my-starter/
    ├── src/main/java
    │   └── com/example/autoconfigure
    │       ├── MyServiceAutoConfiguration.java  // 自动配置类
    │       └── MyServiceProperties.java         // 配置属性绑定
    └── src/main/resources└── META-INF└── spring.factories                 // 注册自动配置
    
  2. 实现自动配置类

    @Configuration
    @EnableConfigurationProperties(MyServiceProperties.class)
    @ConditionalOnClass(MyService.class)
    public class MyServiceAutoConfiguration {@Bean@ConditionalOnMissingBeanpublic MyService myService(MyServiceProperties properties) {return new MyService(properties.getConfig());}
    }
    
  3. 配置属性绑定

    @ConfigurationProperties(prefix = "my.service")
    public class MyServiceProperties {private String config = "default";// getters & setters
    }
    
  4. 注册自动配置

    spring.factories内容:

    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    com.example.autoconfigure.MyServiceAutoConfiguration
    

最佳实践与注意事项

  1. 依赖范围控制

    使用 <optional>true</optional> 标记非必要传递依赖,避免污染用户项目的依赖树。

  2. 条件注解使用

    合理应用 @ConditionalOnProperty@ConditionalOnWebApplication 等注解,确保配置仅在满足条件时生效。

  3. 调试技巧

    启动时添加 --debug 参数可查看自动配置报告。

通过 starter 机制,SpringBoot 实现了开箱即用的体验,开发者无需手动管理复杂依赖关系与 xml 配置,显著提升了开发效率。

SpringBoot 依赖管理机制

SpringBoot 通过统一版本管理模块化 Starter 设计实现高效的依赖管理:

  1. 版本管理

    • 维护了 spring-boot-dependencies BOM(Bill of Materials),预定义了所有官方支持的依赖版本

    • 开发者无需手动指定依赖版本号,例如:

      <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><!-- 无需写<version> -->
      </dependency>
      
    • 所有 Starter 的版本由 SpringBoot 父 POM 统一控制。

  2. 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

依赖管理实现方式

  1. 继承父项目 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
  1. 导入 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)

自动配置联动

依赖管理与自动配置的协同工作:

  1. 当引入 spring-boot-starter-data-redis 时:
    • 自动加入 Jedis、Lettuce 客户端。
    • 自动配置 RedisTemplate Bean。
  2. 条件化配置原理:
    • 通过 @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,是所有 starterstarter,基础核心 starter。

  • spring-boot-starter 导入了一个包 spring-boot-autoconfigure。包里面都是各种场景的 AutoConfiguration 自动配置类

  • 虽然全场景的自动配置都在 spring-boot-autoconfigure 这个包,但是不是全都开启的。

  • 导入哪个场景就开启哪个自动配置。

实现原理与关键组件

  1. @EnableAutoConfiguration 注解

    SpringBoot 应用主类上的 @SpringBootApplication 注解包含 @EnableAutoConfiguration,触发自动配置流程。

    1. 通过 AutoConfigurationImportSelector 类扫描并加载所有符合条件的自动配置类。
  2. 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
      
  3. 条件化注解(Conditional Annotations)

    自动配置类通过条件注解控制是否生效,优先级从高到低如下:

    条件注解作用
    @ConditionalOnClass类路径中存在指定类时生效
    @ConditionalOnMissingBean容器中不存在指定 Bean 时生效(开发者可覆盖默认配置)
    @ConditionalOnProperty配置文件中存在指定属性且匹配值时生效
    @ConditionalOnWebApplication应用类型为 Web 应用时生效
    @ConditionalOnResource类路径中存在指定资源文件时生效

    代码示例

    @Configuration
    @ConditionalOnClass({DataSource.class, EmbeddedDatabaseType.class})
    @EnableConfigurationProperties(DataSourceProperties.class)
    public class DataSourceAutoConfiguration {// 自动配置 DataSource
    }
    

自动配置的工作流程

  1. 启动阶段

    SpringBoot 启动时,AutoConfigurationImportSelector 读取所有 spring.factories 中的自动配置类。

  2. 条件过滤

    遍历所有配置类,通过条件注解过滤掉不满足条件的类(如缺少依赖类、Bean 已存在等)。

  3. Bean 注册

    将符合条件的配置类加载到 Spring 容器,生成对应的 Bean 定义。

  4. 属性绑定

    通过 @EnableConfigurationPropertiesapplication.propertiesapplication.yml 中的属性绑定到配置类。

流程细节梳理

  1. 导入starter-web:导入了 web 开发场景。

    1. 场景启动器导入了相关场景的所有依赖:starter-jsonstarter-tomcatspringmvc
    2. 每个场景启动器都引入了一个 spring-boot-starter,核心场景启动器。
    3. 核心场景启动器引入了 spring-boot-autoconfigure包。
    4. spring-boot-autoconfigure 里面囊括了所有场景的所有配置。
    5. 只要这个包下的所有类都能生效,那么相当于 SpringBoot 官方写好的整合功能就生效了。
    6. SpringBoot 默认却扫描不到 spring-boot-autoconfigure 下写好的所有配置类。(这些配置类给我们做了整合操作),默认只扫描主程序所在的包
  2. 主程序@SpringBootApplication

    1. @SpringBootApplication 由三个注解组成 @SpringBootConfiguration@EnableAutoConfiguratio@ComponentScan

    2. SpringBoot 默认只能扫描自己主程序所在的包及其下面的子包,扫描不到 spring-boot-autoconfigure 包中官方写好的配置类

    3. @EnableAutoConfiguration:SpringBoot 开启自动配置的核心

      • 是由 @Import(AutoConfigurationImportSelector.class) 提供功能:批量给容器中导入组件。

      • SpringBoot 启动会默认加载142个配置类。

      • 142个配置类来自于 spring-boot-autoconfigureMETA-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件指定的。

      • 项目启动的时候利用 @Import 批量导入组件机制把 autoconfigure 包下的142 xxxxAutoConfiguration 类导入进来(自动配置类)。

    4. 按需生效:

      • 并不是这142个自动配置类都能生效。

      • 每一个自动配置类,都有条件注解 @ConditionalOnxxx,只有条件成立,才能生效 。

  3. xxxxAutoConfiguration 自动配置类

    1. 给容器中使用@Bean 放一堆组件。

    2. 每个自动配置类都可能有这个注解 @EnableConfigurationProperties(**ServerProperties**.class),用来把配置文件中配的指定前缀的属性值封装到 xxxProperties 属性类中。

    3. 以 Tomcat 为例:把服务器的所有配置都是以 server 开头的。配置都封装到了属性类中。

    4. 容器中放的所有组件的一些核心参数,都来自于 xxxPropertiesxxxProperties 都是和配置文件绑定。

    5. 只需要改配置文件的值,核心组件的底层参数都能修改

  4. 写业务,全程无需关心各种整合(底层这些整合写好了,而且也生效了)。

总结

  1. 导入 starter,就会导入 autoconfigure 包。

  2. autoconfigure 包里面有一个文件 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports,里面指定的所有启动要加载的自动配置类。

  3. @EnableAutoConfiguration 会自动的把上面文件里面写的所有自动配置类都导入进来,xxxAutoConfiguration 是有条件注解进行按需加载

  4. xxxAutoConfiguration 给容器中导入一堆组件,组件都是从 xxxProperties 中提取属性值。

  5. xxxProperties 又是和配置文件进行了绑定。

**效果:**导入 starter、修改配置文件,就能修改底层行为。

自动配置的调试与验证

  1. 查看生效的自动配置

    启动时添加 --debug 参数,输出 ConditionEvaluationReport

    java -jar your-app.jar --debug
    
    • 报告中会显示:
      • Positive matches(已启用的配置)
      • Negative matches(未启用的配置及原因)
  2. 手动排除自动配置

    application.properties 中排除特定配置类:

    spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
    

自动配置的典型场景

  1. 数据库配置
    • 条件:类路径中存在 DataSource 相关类(如 HikariCP、JDBC Driver)。
    • 行为:自动创建 DataSource Bean,并根据 spring.datasource.* 属性配置连接池。
  2. Web MVC 配置
    • 条件:类路径中存在 spring-webmvc
    • 行为:自动配置 DispatcherServlet、视图解析器、静态资源处理等。
  3. 缓存配置
    • 条件:类路径中存在缓存实现(如 Redis、EhCache)。
    • 行为:自动初始化缓存管理器。

自定义自动配置

  1. 编写自动配置类

    @Configuration
    @ConditionalOnClass(MyService.class) // 当 MyService 存在时生效
    @EnableConfigurationProperties(MyProperties.class) // 绑定属性
    public class MyAutoConfiguration {@Bean@ConditionalOnMissingBean // 容器中无 MyService 时创建public MyService myService(MyProperties properties) {return new MyService(properties.getConfig());}
    }
    
  2. 注册配置类

    src/main/resources/META-INF/spring.factories 中添加:

    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\com.example.MyAutoConfiguration
    

自动配置的局限性

  1. 依赖冲突

    不同 Starter 可能引入冲突的自动配置(如多个数据源配置),需通过 @Primary@Qualifier 解决。

  2. 过度配置

    自动加载不必要的组件可能影响性能,需通过 exclude 显式排除。

  3. 版本兼容性

    第三方 Starter 的自动配置可能与 SpringBoot 版本不兼容,需注意版本匹配。

总结

Spring Boot 的自动配置通过 条件化加载 + 约定优于配置 的机制,实现了极简的项目初始化。开发者只需:

  1. 通过 Starter 引入依赖。
  2. 按需覆盖默认配置(如定义自定义 Bean 或修改属性)。
  3. 理解自动配置原理以高效调试。

这种机制在简化开发的同时,保留了高度的灵活性,是 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

最佳实践

  1. 项目结构规范:主类应置于根包顶层以保证扫描范围
  2. 配置覆盖策略:优先使用 application.properties 而非代码排除
  3. 调试技巧:启动时添加 --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 环境下注册特定的过滤器
@ConditionalOnExpressionSpEL 表达式结果为 true 时生效复杂条件组合判断

底层实现原理

SpringBoot 通过 Condition 接口实现条件判断:

public interface Condition {boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}
  • ConditionContext:提供环境变量、类加载器等上下文信息。
  • AnnotatedTypeMetadata:读取注解元数据。

开发实战示例

  1. 类存在时自动配置
@Configuration
@ConditionalOnClass(DataSource.class)
public class DataSourceAutoConfiguration {// 当类路径存在DataSource时自动配置
}
  1. 组合条件控制
@Bean
@ConditionalOnProperty(name = "cache.enabled", havingValue = "true")
@ConditionalOnMissingBean
public CacheService cacheService() {// 当配置cache.enabled=true且容器无CacheService时创建
}
  1. 自定义条件注解

    1. 实现 Condition 接口:
    public class EnvCondition implements Condition {@Overridepublic boolean matches(...) {return context.getEnvironment().acceptsProfiles("prod");}
    }
    
    1. 定义注解:
    @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'

最佳实践建议

  1. 避免条件冲突:多个条件注解组合使用时注意逻辑完整性。
  2. 谨慎覆盖默认配置:优先使用 @ConditionalOnMissingBean 而非直接覆盖。
  3. 合理排序配置类:使用 @AutoConfigureOrder 控制配置加载顺序。

典型应用场景

  • 多环境配置切换(dev、test、prod)。
  • 模块化功能开关控制。
  • 第三方库的自动适配。
  • 兼容性处理(如不同版本 JDK 的适配)。

属性绑定注解

核心注解 @ConfigurationProperties

  • 作用:将外部配置文件(如 application.ymlapplication.properties)中的属性批量绑定到 Java Bean。

  • 使用场景:需要注入多个关联属性层级化配置时。

  • 特点

    • 类型安全:自动将属性值转换为 Java 类型(如 StringInteger)。
    • 松散绑定:支持属性名多种格式(如 kebab-casecamelCase)。
    • 嵌套对象支持:通过层级结构绑定复杂对象。
  • 示例:

    @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

语法格式

  1. 对象嵌套
person:name: 张三address:province: 浙江city: 杭州street: 西湖大道education:- 小学: 西湖实验小学- 中学: 杭州二中
  1. 集合类型:有两种表示方法。
  • 行内列表:
fruits: [苹果, 香蕉, 橙子]
  • 多行列表:每条数据格式为 - value 中间有一个空格。
fruits:- 苹果- 香蕉- 橙子
  1. 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 才能切换)。
  • 兼容 SLF4J 门面接口。
  • 支持 Log4j2(需引入spring-boot-starter-log4j2)。

SpringBoot 是如何配置日志的

  1. 每个 starter 场景,都会导入一个核心场景 spring-boot-starter
  2. 核心场景引入了日志的所用功能 spring-boot-starter-logging
  3. 默认使用了 logback + slf4j 组合作为默认底层日志。
  4. 日志是系统一启动就要用,xxxAutoConfiguration 是系统启动好了以后放好的组件,后来用的。
  5. 日志是利用监听器机制配置好的。ApplicationListener
  6. 日志所有的配置都可以通过修改配置文件实现。以 logging 开始的所有配置。

示例:

  1. 使用 LoggerFactory.getLogger(类对象)
@RestController
public class HelloController {Logger log = LoggerFactory.getLogger(HelloController.class);@GetMapping("/hello")public String hello(){log.info("日志——方法进来了");return "hello SpringBoot";}}
  1. 使用注解 @Slf4j
@RestController
@Slf4j
public class HelloController {@GetMapping("/hello")public String hello(){log.info("日志——方法进来了");return "hello SpringBoot";}}

日志格式

默认输出格式:

  • 时间和日期:毫秒级精度。
  • 日志级别:ERRORWARNINFODEBUG or TRACE
  • 进程 ID。
  • ---: 消息分割符。
  • 线程名: 使用 [] 包含。
  • Logger 名: 通常是产生日志的类名
  • 消息: 日志记录的内容。

注意: logback 没有 FATAL 级别,对应的是 ERROR

日志级别

  • 由低到高:ALLTRACEDEBUGINFOWARNERRORFATALOFF

  • 只会打印指定级别及以上级别的日志

    • 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 默认有两个组

组名成员
weborg.springframework.core.codecorg.springframework.httporg.springframework.weborg.springframework.boot.actuate.endpoint.weborg.springframework.boot.web.servlet.ServletContextInitializerBeans
sqlorg.springframework.jdbc.coreorg.hibernate.SQLorg.jooq.tools.LoggerListener

日志输出

将日志输出成一个文件:

# 指定文件路径
logging.file.path=
# 指定文件名字
logging.file.name=a.log

如果没有指定文件路径则默认为项目目录。

也可以只在指定文件名字写日志文件的全路径名。

logging.file.name=D:\\a.log

归档与切割

归档:每天的日志单独存到一个文档中。

切割:每个文件10MB,超过大小切割成另外一个文件。

  1. 每天的日志应该独立分割出来存档。如果使用 logback(SpringBoot 默认整合),可以通过 application.properties 文件指定日志滚动规则。
  2. 如果是其他日志系统,需要自行配置(添加 log4j2.xmllog4j2-spring.xml
  3. 支持的滚动规则设置如下:
配置项描述
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 开发

静态资源管理

  1. 默认静态资源路径

    SpringBoot自动映射以下目录的静态资源:

    1. classpath:/static/
    2. classpath:/public/
      例如:src/main/resources/static/js/main.js 可通过 http://localhost:8080/js/main.js 访问2。
  2. 自定义资源路径与缓存控制

    spring.web.resources.static-locations=classpath:/custom-static/
    spring.web.resources.cache.period=3600  # 缓存1小时
    

控制器与请求处理

  1. 定义控制器

    @RestController  // 或 @Controller(需配合模板引擎)
    public class UserController {@GetMapping("/hello")public String hello() {return "Hello, Spring Boot!";}
    }
    
  2. 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);
    }         
    
  3. 参数绑定注解

    • @RequestParam:获取 URL 参数。
    • @RequestBody:解析 JSON 请求体。
    • @ModelAttribute:绑定表单数据。

高级功能

  1. 异常统一处理

    @ControllerAdvice
    public class GlobalExceptionHandler {@ExceptionHandler(Exception.class)public ResponseEntity<String> handleException(Exception e) {return ResponseEntity.status(500).body("服务器错误: " + e.getMessage());}
    }
    
  2. 拦截器实现权限验证

    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

  1. 导入依赖:
<dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.8</version>
</dependency>             
  1. 配置数据源

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
  1. 实体类与 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);
}           
  1. Service 层实现:
@Service
public class UserServiceImpl implements UserService {@Autowiredprivate UserMapper userMapper;@Transactionalpublic User getUserById(Integer id) {return userMapper.selectById(id);}
}          
  1. Controller
@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;@GetMapping("/{id}")public User get(@PathVariable Integer id) {return userService.getUserById(id);}
}            
  1. 事务配置

在主启动类添加注解:

@SpringBootApplication
@EnableTransactionManagement
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}            

关键优化点

  1. 使用 @MapperScan("com.yigongsui.mapper") 替代单个 @Mapper 注解。
  2. 多数据源需配置 @Primary 注解。
  3. 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}.propertiesapplication-{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.yml1
项目根目录配置文件file:./application.yml2
classpath 配置目录classpath:/config/application.yml3
classpath 根目录classpath:/application.yml最低
Nacos 远程配置通过 spring.cloud.nacos.config 指定覆盖本地配置

特殊规则说明

  1. 同目录文件优先级

    若同一路径存在 .properties.yml 文件,优先加载 .properties

  2. Profile 配置文件加载顺序

    1. 加载主配置文件(如 application.yml
    2. 加载激活的 Profile 文件(如 application-dev.yml
    3. 远程配置中心配置最后加载。
  3. 覆盖逻辑示例

    • application.yml 中定义 server.port=8080
    • application-dev.yml 中定义 server.port=9090
    • 最终生效端口为 9090

SpringBoot 生命周期

生命周期机制介绍

SpringBoot 应用的生命周期由 Spring 框架的 ApplicationContextBean 生命周期机制驱动,分为以下核心阶段:

  1. 应用启动阶段
    • 初始化 SpringApplication,加载配置文件和环境变量。
    • 触发 ApplicationStartingEvent 事件。
    • 创建 ApplicationContext,加载 Bean 定义。
    • 执行 CommandLineRunnerApplicationRunner 接口实现类的逻辑。
  2. Bean 生命周期阶段
    • 实例化:通过构造函数或工厂方法创建 Bean。
    • 依赖注入:通过 @Autowired 或 XML 配置注入依赖。
    • 初始化:通过 @PostConstruct 注解或实现 InitializingBean 接口执行初始化逻辑。
    • 销毁:通过 @PreDestroy 注解或实现 DisposableBean 接口执行销毁逻辑。
  3. 应用关闭阶段
    • 触发 ContextClosedEvent 事件。
    • 销毁所有单例 Bean。
    • 关闭 ApplicationContext

使用方法

  1. 自定义 Bean 生命周期方法

    使用注解定义初始化和销毁逻辑:

    @Component
    public class MyService {@PostConstructpublic void init() {System.out.println("Bean 初始化完成");}@PreDestroypublic void cleanup() {System.out.println("Bean 销毁前清理");}
    }           
    
  2. 监听应用生命周期事件

    实现 ApplicationListener 接口监听事件:

    @Component
    public class MyListener implements ApplicationListener<ApplicationReadyEvent> {@Overridepublic void onApplicationEvent(ApplicationReadyEvent event) {System.out.println("应用启动完成");}
    }         
    
  3. 使用 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 的步骤

  1. 添加依赖

    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>
    
  2. 配置 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 示例          
    
  3. 添加注解

    Controller 类和方法上使用注解描述接口:

    @RestController
    @OpenAPIDefinition(info = @Info(title = "用户管理接口"))
    public class UserController {@Operation(summary = "获取用户列表", description = "分页查询用户")@GetMapping("/users")public List<User> getUsers() {// 业务逻辑}
    } 
    
  4. 访问文档界面

    启动应用后,通过以下 URL 访问 Swagger UI:http://localhost:端口/swagger-ui.html

关键注解说明

注解用途
@OpenAPIDefinition定义全局 API 信息
@Operation描述单个接口功能
@Parameter定义接口参数
@Tag对接口分组(替代旧版 @Api

注意事项

  1. 兼容性:SpringBoot 3.x 需使用 springdoc-openapi,旧版 springfox 不再支持。
  2. 安全性:生产环境需通过权限控制 Swagger 访问,避免暴露敏感信息。
  3. 配置简化:若无需自定义配置,依赖添加后即可自动生成文档。

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。

步骤

  1. 添加依赖

    <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    
  2. 启用 Feign 客户端(使用注解 @EnableFeignClients

    @SpringBootApplication
    @EnableFeignClients
    public class Application { ... }
    
  3. 定义接口

    @FeignClient(name = "example-service", url = "http://api.example.com")
    public interface ExampleClient {@GetMapping("/data")String getData();
    }    
    
  4. 注入使用

    @Autowired
    private ExampleClient exampleClient;public void callRemote() {String data = exampleClient.getData();
    }      
    

RPC 框架(如 gRPC)

适用于高性能二进制通信,需额外配置协议文件和服务端/客户端实现。

实现步骤

  1. 添加 grpc-spring-boot-starter 依赖。
  2. 定义 .proto 文件描述服务接口。
  3. 生成 Java 代码并实现服务逻辑。

注意事项

  1. 版本兼容性:SpringBoot 3.x 需搭配 SpringCloud 2022.x 及以上版本。
  2. 性能优化:异步场景优先选择 WebClient,同步场景可使用 RestTemplate
  3. 异常处理:需捕获 WebClientResponseExceptionFeignException 等特定异常。

SpringSecurity

SpringSecurity 是 Spring 生态中专注于安全管理的框架,提供身份验证(Authentication)、授权(Authorization)、会话管理等核心功能,通过声明式配置简化安全控制逻辑。

核心功能

  • 身份验证:验证用户身份(如用户名密码、OAuth2)。
  • 授权:控制用户对资源的访问权限(如角色/权限校验)。
  • 会话管理:管理用户会话生命周期与安全性。
  • 安全防护:防御 CSRF、XSS、SQL 注入等攻击。

SpringBoot 集成 SpringSecurity

  1. 导入依赖:
<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>
  1. 配置基础安全规则

创建 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();}
}
  1. 自定义用户服务(内存示例)
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;
}
  1. 启动并测试

运行项目后,访问受保护接口(如 /home)将自动跳转到默认登录页,使用配置的用户名密码登录。

进阶配置

  1. 基于注解的权限控制

    使用 @PreAuthorize 实现方法级权限校验:

    @GetMapping("/admin")
    @PreAuthorize("hasRole('ADMIN')")
    public String adminPage() {return "Admin Panel";
    }
    
  2. 密码加密配置

    推荐使用 BCryptPasswordEncoder

    @Bean
    public PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();
    }
    
  3. 动态权限管理

    通过实现 UserDetailsService 和自定义权限逻辑,从数据库加载用户权限。

总结

SpringSecurity 通过声明式配置简化安全逻辑,SpringBoot 通过自动配置进一步降低集成成本。实际项目中需结合数据库、加密算法和动态权限管理实现完整方案。


http://www.mrgr.cn/news/100072.html

相关文章:

  • python_BeautifulSoup提取html中的信息
  • 基于HTML+CSS实现的动态导航引导页技术解析
  • OpenCv高阶(十)——光流估计
  • Linux软硬链接和动静态库(20)
  • Arm GICv3中断处理模型解析
  • 【深度强化学习 DRL 快速实践】策略梯度算法 (PG)
  • Pycharm(十六)面向对象进阶
  • 红黑树——如何靠控制色彩实现平衡的?
  • DPIN河内AI+DePIN峰会:共绘蓝图,加速构建去中心化AI基础设施新生态
  • 【Harmony OS】组件
  • Java 安全:如何实现用户认证与授权?
  • Chrmo手动同步数据
  • 一款好用的桌面待办工具,轻松掌控时间沙漏!
  • 【Python数据库与后端开发】从ORM到RESTful API
  • 【专题刷题】二分查找(二)
  • 单机无穷大系统暂态稳定性仿真Matlab模型
  • 【Kafka 初学】为什么启动 Kafka 前必须先启动 Zookeeper
  • Canvas入门教程!!【Canvas篇二】
  • 第TR5周:Transformer实战:文本分类
  • 基于Axure的动态甘特图设计:实现任务增删改与时间拖拽交互