当前位置: 首页 > 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 通过自动配置进一步降低集成成本。实际项目中需结合数据库、加密算法和动态权限管理实现完整方案。

相关文章:

SpringBoot 学习

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

Q2桥门式起重机司机考试复习重点

Q2桥门式起重机司机考试复习重点 Q2桥门式起重机司机属于特种设备作业人员&#xff0c;理论考试重点复习时应重点掌握以下内容&#xff1a; 1、基础知识 桥门式起重机的结构组成&#xff08;大车、小车、起升机构、电气系统等&#xff09;。 主要技术参数&#xff08;额定起…...

并发设计模式实战系列(7):Thread Local Storage (TLS)

&#x1f31f; 大家好&#xff0c;我是摘星&#xff01; &#x1f31f; 今天为大家带来的是并发设计模式实战系列&#xff0c;第七章Thread Local Storage (TLS)&#xff0c;废话不多说直接开始~ 目录 一、核心原理深度拆解 1. TLS内存模型 2. 关键特性 二、生活化类比&a…...

本地使用Ollama部署DeepSeek

以下是在本地使用Ollama部署DeepSeek的详细教程&#xff0c;涵盖安装、修改安装目录、安装大模型以及删除大模型的操作步骤。 安装Ollama 1. 系统要求 确保你的系统满足以下条件&#xff1a; 操作系统&#xff1a;macOS、Linux或者Windows。足够的磁盘空间和内存。 2. 安装…...

通过VSCode远程连接到CentOS7/Ubuntu18等老系统

通过VSCode远程连接到CentOS7/Ubuntu18等老系统 背景 VSCode的远程连接插件Remote SSH一直以来是简单好用的远程工具。然而&#xff0c;2025年2月之后的版本在远程安装vscode-server时&#xff0c;预编译的server依赖glibc 2.28&#xff0c;这就要求Linux远程机的glibc版本应…...

Python在AI虚拟教学视频开发中的核心技术与前景展望

Python在AI虚拟教学视频开发中的核心技术与前景展望 一、引言&#xff1a;AI虚拟教学的技术革新 随着教育数字化转型加速&#xff0c;AI虚拟教学视频凭借个性化、沉浸式体验成为教育科技的新风口。Python以其强大的多模态处理能力、丰富的开源生态和跨领域兼容性&#xff0c;成…...

【金仓数据库征文】金仓数据库:开启未来技术脑洞,探索数据库无限可能

我的个人主页 我的专栏&#xff1a; 人工智能领域、java-数据结构、Javase、C语言&#xff0c;希望能帮助到大家&#xff01;&#xff01;&#xff01; 点赞&#x1f44d;收藏❤ 目录 引言&#xff1a;数据库进化的下一站 —— 未来科技的无限可能金仓数据库简介&#xff1a;国…...

深入掌握Redis主从复制:原理、配置与生产级实践指南

一、主从复制核心价值与适用场景 1.1 核心价值矩阵 数据安全&#xff1a;多节点冗余存储&#xff0c;避免单点数据丢失 服务可用性&#xff1a;主节点故障时可快速切换从节点 性能扩展&#xff1a;通过横向扩展从节点提升读吞吐量 运维便利&#xff1a;从节点可承担备份、分…...

springboot如何管理多数据源?

静态多数据源管理 配置多个数据源 :创建多个数据源的配置类,通常使用 @ConfigurationProperties 注解来绑定配置文件中的数据源属性,并通过 @Bean 注解定义多个 DataSource Bean 。例如: 配置类: @Configuration public class DataSourceConfig {@Bean(name = "prima…...

基于风力推进器控制的小球实验装置设计与研究

目录 完整论文下载链接放在文章结尾,有需要自行下载。 目录 摘 要 1 引 言 2 概述 2.1 风控小球系统概述 2.2 本设计方案思路 2.3 研发方向和技术关键 2.4 主要技术指标 3 总体设计 4 硬件设计 4.1 单片机最小系统 4.2 供电接口电路 4.3 Openmv摄像头…...

Swift闭包(Closure)深入解析与底层原理

前言 在Swift开发中&#xff0c;闭包是一个非常重要且强大的特性。本文将深入探讨Swift闭包的底层实现原理&#xff0c;帮助开发者更好地理解和使用这一特性。 1. 什么是闭包 闭包是自包含的函数代码块&#xff0c;可以在代码中被传递和使用。它不仅可以像函数一样执行代码&…...

【DE-III】基于细节增强的模态内和模态间交互的视听情感识别

abstract 在视听情感识别(AVER)中,捕捉视频和音频模态之间复杂的时间关系是至关重要的。然而,现有的方法缺乏对局部细节的关注,如视频帧之间的面部状态变化,这会降低特征的可区分性,从而降低识别准确率。 为此,本文提出了一种用于AVER的细节增强的模态内和模态间交互…...

c++11 :智能指针

目录 一 为什么需要智能指针&#xff1f; 二 智能指针的使用及原理 1. RAII 2. auto_ptr 3. unique_ptr 4. shared_ptr 5. weak_ptr 三 内存泄漏 1.什么是内存泄漏&#xff0c;内存泄漏的危害 2. 如何避免内存泄漏&#xff1f; 一 为什么需要智能指针&#xff1f; …...

Linux解压tar.gz包的正确姿势(附赠防抓狂指南)

一、为什么你的解压命令总报错&#xff1f; 每次看到.tar.gz后缀是不是心里一紧&#xff1f;&#xff08;别装了&#xff01;我都看到你偷偷打开浏览器查命令的样子了&#xff09;这个在Linux界横行霸道的压缩格式&#xff0c;其实用对了方法比Windows的zip还简单。今天咱们不…...

MCP协议:让AI从“话痨”变“实干家”的神奇魔法

一、MCP 协议&#xff1a;AI 界的 “万能插头” 是啥来头&#xff1f; 1.1 从 “动口不动手” 到 “全能打工人” 你以为 AI 只会陪你聊天、写文案&#xff1f;那你可小瞧它啦&#xff01;MCP 协议&#xff08;Model Context Protocol&#xff09;&#xff0c;堪称 AI 的 “瑞…...

如何在SpringBoot中通过@Value注入Map和List并使用YAML配置?

在SpringBoot开发中&#xff0c;我们经常需要从配置文件中读取各种参数。对于简单的字符串或数值&#xff0c;直接使用Value注解就可以了。但当我们需要注入更复杂的数据结构&#xff0c;比如Map或者List时&#xff0c;该怎么操作呢&#xff1f;特别是使用YAML这种更人性化的配…...

记一次调用大华抓拍SDK并发优化

目录 一、问题分析 二、解决思路 三、贴代码 四、总结 一、问题分析 按惯例上问题&#xff1a; 设备告警采用高电平持续模式&#xff1a;一次开&#xff0c;不主动关就一直处于告警状态。 并发时多个请求下发 setDVRAlarmOutConfig&#xff0c;导致状态混乱。 “开 -&g…...

打破认知!没论文没竞赛,我的暑期实习上岸秘籍:简历要敢 “吹”,面试靠巧 “聊”

前言 以下教程仅针对本人的大大小小几十场暑期实习面试的经验总结&#xff0c;个人背景&#xff08;双9&#xff0c;无论文、无竞赛、无大厂实习、无奖。&#xff09;。简历几易其稿&#xff0c;相对于原来的初版&#xff0c;可谓是脱胎换骨&#xff0c;洗经易髓。 二月中旬开…...

为何 RAG 向量存储应优先考虑 PostgreSQL + pgvector 而非 MySQL?

构建检索增强生成&#xff08;RAG&#xff09;系统已成为释放大型语言模型&#xff08;LLM&#xff09;潜力的关键范式。通过将 LLM 的推理能力与外部知识库的实时、特定信息相结合&#xff0c;RAG 能够生成更准确、更相关、更值得信赖的回答。而这个“外部知识库”的核心&…...

LangChain LCEL表达式语言简介

LangChain表达式语言&#xff08;LCEL&#xff09;是专为构建AI应用链设计的声明式编程框架&#xff0c;通过管道符|实现组件无缝衔接&#xff0c;支持流式处理、异步调用等生产级特性。其核心优势在于零代码改动实现原型到生产的过渡&#xff0c;同时保持代码简洁性和可维护性…...

智能座舱背后的秘密:智能座舱测试如何“具身智能”

在上期文章《智能座舱背后的秘密&#xff1a;AI赋能测试如何改写驾乘体验》中&#xff0c;我们聊到了“智能座舱”已成为车企争夺用户心智的核心战场、智能座舱功能体验进化、AI赋能座舱测试将突破“场景覆盖、情感量化、角色/场景衍生”技术实现方面的三大困局&#xff0c;并在…...

鸿蒙-试一下属性字符串:除了Span之外,如何在同一个Text组件中展示不同样式的文字

文章目录 前言简介有哪些类型拉出来溜溜Text SpanStyledString其他CustomSpan先看一下构造函数onMeasure(measureInfo: CustomSpanMeasureInfo): CustomSpanMetricsonDraw(context: DrawContext, drawInfo: CustomSpanDrawInfo) 遗留问题 前言 在开发中&#xff0c;经常会遇到…...

今日最新漂亮的早上好图片祝福,最真的牵挂,永远的祝福

1、清晨的一个问候给你一个新的心情、一个祝福带给你新的起点、一个关心带给你一个新的愿望。祝福你心中常有快乐涌现&#xff01;早安&#xff01; 2、人过花甲万事休&#xff0c;唯有健康不可丢&#xff0c;荣华富贵皆浮云&#xff0c;逍遥自在渡岁月&#xff01;时光匆匆&am…...

MySQL 库的操作 -- 增删改查,备份和恢复,系统编码

文章目录 库的操作增删改查数据库的查看和创建查看当前位于哪个数据库中数据库的删除总结显示数据库的创建语句修改数据库 认识系统编码数据库的编码问题查看系统默认的字符集和效验规则校验规则对数据库的影响 数据库的备份和恢复备份还原备份的是一张表 查看数据库的连接情况…...

【c++11】c++11新特性(下)(可变参数模板、default和delete、容器新设定、包装器)

&#x1f31f;&#x1f31f;作者主页&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所属专栏&#xff1a;C 目录 前言 五、可变参数模板 1. 概念及简单定义 2. 包扩展 六、 default和delete 七、容器新设定 1. 新容器 2. 新接口 emplace系列接口 八、函数包…...

fps项目总结:生成武器子弹

文章目录 spawn actor&#xff1a;生成武器固定生成&#xff1a;因为武器的碰撞设为noCollision attach actor to component&#xff1a;将武器附加到骨骼上&#xff0c;成为mesh的子组件对齐到目标&#xff1a;对齐到插槽 子弹阻挡的前提是根组件为碰撞体子弹对碰撞体全是阻挡…...

大模型备案对模型训练语料的要求

昨天接到一位客户的咨询&#xff0c;说他们的模型还在开发阶段&#xff0c;想提前了解一下大模型备案政策中对于模型训练语料有什么具体要求&#xff0c;提前规避一下。客户确实有前瞻性&#xff0c;考虑得比较充分。训练语料在研发阶段至关重要&#xff0c;直接影响模型的性能…...

Ethan独立开发产品日报 | 2025-04-24

1. Peek AI个人财务教练&#xff0c;帮助你做出决策。 Peek的人工智能助手提供主动的跟踪服务——它会分析你的消费习惯&#xff0c;并以细腻而积极的方式帮助你调整这些习惯。没有评判&#xff0c;也没有负担。就像是为你的财务量身定制的Spotify Wrapped&#xff0c;完美贴…...

egg环境搭建

前言 egg.js 是由阿里开源的面向企业级开发的 Node.js 服务端框架&#xff0c;它的底层是由 Koa2 搭建。 Github&#xff1a;https://github.com/eggjs/egg&#xff0c;目前 14.8K Star&#xff0c;egg 很适合做中台。 安装 首先&#xff0c;你要 确保 Node 已经配置环境变量…...

Linux的基础指令

目录 1、Shell及运行原理 2、热键 3、Linux的基础知识 4、Linux的基础指令 4.1 man 4.2 clear&&history&&whoami 4.3 pwd 4.4 ls 4.5 cd 4.6 mkdir&&touch 1. mkdir 2. touch 4.7 rmdir&&rm 1. rmdir 2. rm 4.8 cp&&mv…...

第一部分:git基本操作

目录 1、git初识 1.1、存在的问题 1.2、版本控制器 1.3、git安装 1.3.1、CentOS平台 1.3.2、ubuntu平台 2、git基本操作 2.1、创建仓库 2.2、配置git 3、工作区、暂存区、版本库 4、基本操作 4.1、场景一 4.2、场景二 4.3、修改文件 5、版本回退 6、撤销修改 …...

Kafka和其他组件的整合

Kafka和其他组件的整合 1.Kafka和Flume的整合 需求1&#xff1a;利用flume监控某目录中新生成的文件&#xff0c;将监控到的变更数据发送给kafka&#xff0c;kafka将收到的数据打印到控制台&#xff1a; 在flume/conf下添加.conf文件&#xff0c; vi flume-kafka.conf # 定…...

学习AI必知的20大概念

&#x1f3af;AI开发者必知的20大概念 ​&#x1f916; 机器学习&#xff1a;基础算法和模型训练。 &#x1f9e0; 深度学习&#xff1a;复杂表示学习。 &#x1f310; 神经网络&#xff1a;非线性关系建模。 &#x1f5e3;️ NLP&#xff1a;文本处理和理解。 &#x1f441;️…...

VRRP与防火墙双机热备实验

目录 实验一&#xff1a;VRRP负载均衡与故障切换 实验拓扑​编辑一、实验配置步骤 1. 基础网络配置 2. VRRP双组配置 二、关键验证命令 1. 查看VRRP状态 2. 路由表验证 三、流量分析 正常负载均衡场景&#xff1a; 故障切换验证&#xff1a; 实验二&#xff1a;防火…...

【金仓数据库征文】——选择金仓,选择胜利

目录 第一部分&#xff1a;金仓数据库——开创数据库技术的新时代 1.1 金仓数据库的技术底蕴 1.2 高可用架构与灾备能力 1.3 分布式架构与弹性扩展能力 第二部分&#xff1a;金仓数据库助力行业数字化转型 2.1 电信行业&#xff1a;核心系统国产化替代 2.2 医疗行业&…...

微软官网Win10镜像下载快速获取ISO文件

如何从微软官网轻松下载win10镜像&#xff1f;win10镜像的下载方式主要包括两种&#xff1a; 目录 一&#xff1a;借助官方工具 二&#xff1a;直接微软官网通过浏览器进行下载。 三&#xff1a;实现方法与步骤&#xff1a; 1&#xff1a;利用微软官方提供的MediaCreationT…...

发放优惠券

文章目录 概要整体架构流程技术细节小结 概要 发放优惠券 处于暂停状态&#xff0c;或者待发放状态的优惠券&#xff0c;在优惠券列表中才会出现发放按钮&#xff0c;可以被发放&#xff1a; 需求分析以及接口设计 需要我们选择发放方式&#xff0c;使用期限。 发放方式分…...

【专题刷题】二分查找(二)

&#x1f4dd;前言说明&#xff1a; 本专栏主要记录本人的基础算法学习以及LeetCode刷题记录&#xff0c;按专题划分每题主要记录&#xff1a;&#xff08;1&#xff09;本人解法 本人屎山代码&#xff1b;&#xff08;2&#xff09;优质解法 优质代码&#xff1b;&#xff…...

如何避免IDEA每次打开新项目都重复配置Maven?

每次打开新项目都要重新设置Maven路径&#xff1f;每次导入工程都要手动调整settings.xml&#xff1f;如果你也受够了IDEA这种“健忘”行为&#xff0c;那么这篇文章就是为你准备的&#xff01;今天我们就来彻底解决这个问题&#xff0c;让IDEA记住你的Maven配置&#xff0c;一…...

【Linux网络编程】应用层协议HTTP(实现一个简单的http服务)

目录 前言 一&#xff0c;HTTP协议 1&#xff0c;认识URL 2&#xff0c;urlencode和urldecode 3&#xff0c;HTTP协议请求与响应格式 二&#xff0c;myhttp服务器端代码的编写 HTTP请求报文示例 HTTP应答报文示例 代码编写 网络通信模块 处理请求和发送应答模块 结…...

深度解析之算法之分治(快排)

44.颜色分类 题目链接 给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums &#xff0c;原地 对它们进行排序&#xff0c;使得相同颜色的元素相邻&#xff0c;并按照红色、白色、蓝色顺序排列。 我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。 必须在不使用库内置…...

【金仓数据库征文】-金仓数据库性能调优 “快准稳” 攻略:实战优化,让数据处理飞起来

我的个人主页 我的专栏&#xff1a; 人工智能领域、java-数据结构、Javase、C语言&#xff0c;希望能帮助到大家&#xff01;&#xff01;&#xff01; 点赞&#x1f44d;收藏❤ 目录 一、KingbaseES金仓数据库简介二、快速入门&#xff1a;金仓数据库下载与安装指南三、“快”…...

DPIN河内AI+DePIN峰会:共绘蓝图,加速构建去中心化AI基础设施新生态

近日&#xff0c;一场聚焦前沿科技融合的盛会——AIDePIN峰会在越南河内成功举办。此次峰会由DPIN、QPIN及42DAO等Web3领域的创新项目联合组织&#xff0c;汇聚了众多Web3行业领袖、技术专家与社区成员。峰会于2025年4月19日举行&#xff0c;其核心议题围绕去中心化物理基础设施…...

vscode和git 踩坑

git init经常 在 vscode push错误问题: 正确姿势&#xff1a;先 GitHub 上建仓库 → git clone 拉到本地 → 再用 VSCode 打开编辑 ❌ 不是&#xff1a;VSCode 里 git init → 再去 GitHub 选个仓库绑定 举个对比 操作流程是否推荐后果GitHub 创建仓库 → git clone → 用 VSC…...

C++11介绍

目录 一、C11的两个小点 1.1、decltype 1.2、nullptr 二、列表初始化 2.1、C98传统的{} 2.2、C11中的{} 2.3、C11中的std::initializer_list 三、右值引用和移动语义 3.1、左值和右值 3.2、左值引用和右值引用 3.3、引用延长生命周期 3.4、左值和右值的参数匹配 3…...

AI数字人:繁荣背后的伦理困境与法律迷局(8/10)

摘要&#xff1a;本文深入剖析 AI 数字人从虚拟走向现实的历程&#xff0c;阐述其融合多技术实现从静态到动态交互的跨越&#xff0c;爆发式应用于各领域带来的商业价值与社会影响&#xff0c;同时直面由此引发的伦理法律挑战&#xff0c;包括身份认同、数据隐私、责任归属及权…...

SOLID 原则在单片机环境下的 C 语言实现示例,结合嵌入式开发常见场景进行详细说明

1. 单一职责原则 (SRP) 定义:一个模块(函数/文件)只负责一个功能。 示例:传感器数据采集与处理分离 // SensorAdc.h - 仅负责ADC原始数据采集 typedef struct { uint16_t (*ReadRaw)(void); // 原始数据读取接口 } SensorAdc; // SensorProcessor.h - 仅负责数据处理…...

RT Thread 发生异常时打印输出cpu寄存器信息和栈数据

打印输出发生hardfault时,当前栈十六进制数据和cpu寄存器信息 在发生 HardFault 时,打印当前栈的十六进制数据和 CPU 寄存器信息是非常重要的调试手段。以下是如何实现这一功能的具体步骤和示例代码。 1. 实现 HardFault 处理函数 我们需要在 HardFault 中捕获异常上下文,…...

SQL 函数进行左边自动补位fnPadLeft和FORMAT

目录 1.问题 2.解决 方式1 方式2 3.结果 1.问题 例如在SQL存储过程中&#xff0c;将1 或10 或 100 长度不足的时候&#xff0c;自动补足长度。 例如 1 → 001 10→ 010 100→100 2.解决 方式1 SELECT FORMAT (1, 000) AS FormattedNum; SELECT FORMAT(12, 000) AS Form…...

Unity中数据和资源加密(异或加密,AES加密,MD5加密)

在项目开发中,始终会涉及到的一个问题,就是信息安全,在调用接口,或者加载的资源,都会涉及安全问题,因此就出现了各种各样的加密方式。 常见的也是目前用的最广的加密方式,分别是:DES、3DES、AES、MD5、XOR(异或) 其中DES、3DES、AES、MD5用在数据加密中偏多,特别是…...