Spring Boot学习记录
SpringBoot 概述
Spring Boot 是在 Spring Frame 的基础上,简化了 Spring frame 的开发,可是使用 Spring Boot 来快速的创建 java 应用。 提供一系列大类项目常见的非功能特性(如嵌入式服务器、安全、度量、健康检查和外部化配置)。
- 构建工具:Maven 或 Gradle
- 支持的 Servlet 容器:Tomcat、Jetty、Undertow(Jakarta EE)
SpringBoot 入门指导
依赖管理
在 Spring Boot 的官方文档中提供了一个它所支持的依赖的列表。在引入 Maven 依赖时我们不需要指定依赖的版本,Spring boot 会自动管理。
Maven 构建 Spring Boot
当然你也可以使用 Gradle 来构建,这里只讲述 Maven 的构建方式,本文之后的相关文章,默认都是基于 maven 的。
Starter
Starter 是一系列开箱即用的依赖,你可以在你的应用程序中导入它们。 通过你 Starter,可以获得所有你需要的 Spring 和相关技术的一站式服务
以下是 Spring Boot 在 org.springframework.boot 这个 groupId 下提供的常用 starter 组件。
- spring-boot-starter :核心,包括自动注入,日志等
- spring-boot-starter-aop:简化在 Spring Boot 应用中集成 Spring AOP 和 AspectJ 实现面向切面编程(AOP)的开发过程。
- spring-boot-starter-cache:实现对数据的缓存管理,从而减少重复计算或数据库访问,提升应用性能
- spring-boot-starter-bache:简化了批处理作业的开发和部署,让开发者能够快速实现高性能、可容错、可监控的批处理任务。
- spring-boot-starter-data:与数据库相关的依赖包,例如:Jpa,JDBC,Redis,rest 等
- spring-boot-starter-jdbc :通过自动配置简化数据库连接、SQL 执行、资源管理等底层操作,让开发者无需编写繁琐的数据库访问样板代码。
- spring-boot-starter-json:于简化在 Spring Boot 应用中处理 JSON 数据的开发过程。
- spring-boot-starter-test:测试代码使用的
- spring-boot-starter-security:Spring Security 是 Spring 生态中专注于身份认证(Authentication)和授权(Authorization)的安全框架,通过该 Starter,开发者可以快速为应用添加安全防护能力(如用户登录验证、权限控制、防 CSRF 攻击等),无需手动配置复杂的安全基础设施。
- spring-boot-starter-oauth2-authorization-server:整合 Spring Security OAuth2 Authorization Server 与 Spring Boot 的 Starter,通过自动配置机制简化授权服务器核心组件(如令牌生成、客户端管理、端点暴露)的初始化,无需手动搭建复杂的 OAuth2.0 基础设施
- spring-boot-starter-quartz 它通过自动配置简化了复杂定时任务的开发流程。企业级应用中处理定时任务的首选方案。对于需要精确控制任务执行时间、支持动态调整或运行在分布式环境的场景(如电商订单超时处理、系统定时备份),
- spring-boot-starter-validation:spring-boot-starter-validation 是 Spring Boot 提供的官方 Starter(启动器),用于简化在 Spring Boot 应用中集成 数据校验 功能的开发过程。
- spring-boot-starter-web: 是开发 Spring Boot Web 应用的基石,它通过自动配置整合了 Spring MVC 和嵌入式服务器,极大简化了 Web 应用的搭建流程。
- spring-boot-starter-websocket:使用 Websocket 的依赖包
- spring-boot-starter-webflux :是构建响应式 Web 应用的核心依赖,它基于 Spring WebFlux 框架和 Reactive Streams 规范,提供了异步非阻塞的编程模型,适合处理高并发、I/O 密集型场景。
- spring-boot-starter-log4j2:使用日志的一个依赖包
基础类
- @SpringBootApplication:启动类,它默认会扫描当前类下的所有子包
1 | import org.springframework.boot.SpringApplication; |
- @Configuration:配置类,在代码上添加这个注解就可以使用代码来配置信息
@Import 注解可以用来导入额外的配置类。 另外,你可以使用 @ComponentScan 来自动扫描加载所有 Spring 组件,包括 @Configuration 类
自动配置
Spring Boot 的自动装配机制会试图根据你所添加的依赖来自动配置你的 Spring 应用程序。 例如,如果你添加了 HSQLDB 依赖,而且你没有手动配置任何 DataSource Bean,那么 Spring Boot 就会自动配置内存数据库。@EnableAutoConfiguration 或 @SpringBootApplication 注解添加到你的 @Configuration 类中,从而开启自动配置功能。
逐步取代自动配置
自动配置是非侵入性的。 在任何时候,你都可以开始定义你自己的配置来取代自动配置的特定部分。 例如,如果你添加了你自己的 DataSource bean,默认的嵌入式数据库支持就会“退步”从而让你的自定义配置生效。
禁用自用装配
如果你想禁用掉项目中某些自动装配类,你可以在 @SpringBootApplication 注解的 exclude 属性中指定
1 | import org.springframework.boot.autoconfigure.SpringBootApplication; |
如果要禁用的自动装配类不在 classpath 上(没有导入),那么你可以在注解的 excludeName 属性中指定类的全路径名称
Spring Bean 和依赖注入
你可以使用任何标准的 Spring 技术来定义你的 Bean 以及依赖注入关系。 推荐使用构造函数注入,并使用 @ComponentScan 注解来扫描 Bean。
如果你按照上面的建议构造你的代码(将你的启动类定位在顶级包中),你可以在启动类添加 @ComponentScan 注解,也不需要定义它任何参数, 你的所有应用组件(@Component、@Service、@Repository、@Controller 和其他)都会自动注册为 Spring Bean。
然后使用@Autowired 就可以调用容器中注入的类
@SpringBootApplication 注解
如果你想实现自动配置、组件扫描,并且能够在他们的 “application class “上定义额外的配置。 一个 @SpringBootApplication 注解就可以用来启用这三个功能,如下。
@EnableAutoConfiguration:启用 Spring Boot 的自动配置机制。
@ComponentScan:对应用程序所在的包启用 @Component 扫描
@SpringBootConfiguration:允许在 Context 中注册额外的 Bean 或导入额外的配置类。这是 Spring 标准的 @Configuration 的替代方案,有助于在你的集成测试中检测配置。
示例:
1 | import org.springframework.boot.SpringApplication; |
好了,我们已经基本了解了 Spring Boot 的使用,接下来,我们将介绍 Spring Boot 如何来进行开发
Spring Boot 核心
SpringApplication
通过 SpringApplication 类,我们可以从 main() 方法中启动 Spring 应用程序。 在许多情况下,你可以直接调动 SpringApplication.run 静态方法
1 | import org.springframework.boot.SpringApplication; |
**在项目中有一些类或方法往往需要在程序启动完成之后立马执行,那么我们就可以通过 SpringApplication.run()方法来实现
懒加载化
SpringApplication 允许应用程序被懒初始化。 当启用懒初始化时,Bean 在需要时被创建,而不是在应用程序启动时。懒初始化可以减少应用程序的启动时间。spring.main.lazy-initialization=true
缺点:延迟发现程序出现的问题,如果一个配置错误的 Bean 被懒初始化了,那么在启动过程中就不会再出现故障,问题只有在 Bean 被初始化时才会显现出来。 还必须注意确保 JVM 有足够的内存来容纳应用程序的所有 Bean,而不仅仅是那些在启动期间被初始化的 Bean。
就是 Spring Boot 项目启动后所生成的那个图案。
方法:启动时打印的 Banner 可以通过在 classpath 中添加 banner.txt 文件或通过将 spring.banner.location 属性设置为该文件的位置来自定义。
自定义 SpringApplication
如果 SpringApplication 的默认值不符合你的需求,你可以创建一个实例并对其进行自定义
示例:
1 | import org.springframework.boot.Banner; |
也可以通过使用 application.properties 文件来配置 SpringApplication
可用性
Spring Boot 对常用的 “liveness” 和 “readiness” 可用性状态提供了开箱即用的支持。
Liveness State:一个应用程序的 “Liveness” 状态告诉我们它的内部状态是否允许它正常工作,或者在当前失败的情况下自行恢复。 一个 broken 状态的 “Liveness” 状态意味着应用程序处于一个无法恢复的状态,基础设施应该重新启动应用程序。
Spring Boot 应用程序的内部状态大多由 Spring ApplicationContext 表示。如果 application context 已成功启动,Spring Boot 就认为应用程序处于有效状态。
Readiness State:应用程序的 “Readiness” 状态告诉平台,该应用程序是否准备好处理流量。 failing 状态的 “Readiness” 告诉平台,它暂时不应该将流量发送到该应用程序。 这通常发生在启动期间,当 CommandLineRunner 和 ApplicationRunner 组件还在被处理的时候,或者是应用程序觉得目前负载已经到了极限,不能再处理额外的请求的时候。
Application 时间和监听器
注册:SpringApplication.addListeners(…)或SpringApplicationBuilder.listeners(…)
若想使其自动注册:
- 添加 META-INF/spring.factories 文件
- 配置
org.springframework.context.ApplicationListener=com.example.project.MyListener
Web 环境
SpringApplication 会试图帮你创建正确类型的 ApplicationContext。 确定为 WebApplicationType 的算法如下。
如果 Spring MVC 存在,就会使用 AnnotationConfigServletWebServerApplicationContext。
如果 Spring MVC 不存在而 Spring WebFlux 存在,则使用 AnnotationConfigReactiveWebServerApplicationContext。
否则,将使用 AnnotationConfigApplicationContext。
访问应用参数
如果你需要访问传递给 SpringApplication.run(..) 的命令行参数,你可以注入一个 org.springframework.boot.ApplicationArguments bean。 通过 ApplicationArguments 接口,你可以访问原始的 String[] 参数以及经过解析的 option 和 non-option 参数。
1 | import java.util.List; |
提前启动代码
如果你需要在 SpringApplication 启动后运行一些特定的代码,你可以实现 ApplicationRunner 或 CommandLineRunner 接口。 这两个接口以相同的方式工作,并提供一个单一的 run 方法,该方法在 SpringApplication.run(…) 执行完毕之前被调用。
1 | import org.springframework.boot.CommandLineRunner; |
程序退出
每个 SpringApplication 都向 JVM 注册了一个 shutdown hook,以确保 ApplicationContext 在退出时优雅地关闭。
如果 Bean 希望在调用 SpringApplication.exit() 时返回特定的退出代码,可以实现 org.springframework.boot.ExitCodeGenerator 接口。
1 | import org.springframework.boot.ExitCodeGenerator; |
远程管理 Spring Boot 应用
通过指定 spring.application.admin.enabled 属性,可以启用应用程序的管理相关功能。,具体使用时自己查就可以,我们只需要知道有这个功能
外部化配置
Spring Boot 可以让你将配置外部化,这样你就可以在不同的环境中使用相同的应用程序代码。
@Value:来注入配置文件的属性值
Spring Boot 使用一个非常特别的 PropertySource 顺序,旨在允许合理地重写值。 后面的 property source 可以覆盖前面属性源中定义的值。 按以下顺序考虑。
默认属性<@Configuration 类上的@PropertySource<配置文件 application.properties
访问命令行属性
默认情况下,SpringApplication 会将任何命令行选项参数(即以 — 开头的参数,如 —server.port=9000 )转换为 property 并将其添加到 Spring Environment 中,命令行属性总是优先于基于文件的属性源。
JSON Application Propertis
环境变量和系统属性往往有限制,这意味着有些属性名称不能使用
我们可以使用一个 JSON 来解决这个问题,他会先解析并将解析之后的属性加到环境变量
示例:$ SPRING_APPLICATION_JSON='{"my":{"name":"test"}}' java -jar myapp.jar
切换配置文件名字:java -jar myproject.jar --spring.config.name=myproject
特定文件
除了 application 属性文件,Spring Boot 还将尝试使用 application-{profile} 的命名惯例加载 profile 特定的文件。 例如,如果你的应用程序激活了名为 prod 的配置文件(spring.profiles.active=prod)并使用 YAML 文件,那么 application.yaml 和 application-prod.yaml 都将被考虑。特定文件总是优先于非特定文件
导入额外的数据或文件
application properties 中可以使用 spring.config.import 属性从其他地方导入更多的配置数据。
示例:
1 | // 导入数据 |
使用配置树
当在云平台(如 Kubernetes)上运行应用程序时,你经常需要读取平台提供的配置值。 将环境变量用于此类目的并不少见,但这可能有缺点,特别是如果该值是 secret 的。
作为环境变量的替代方案,许多云平台现在允许你将配置映射到挂载的数据卷。
两种常见的 volume 挂载模式:
- 一个文件包含一套完整的属性(通常写成 YAML)。
使用 spring.config.import 直接导入 YAML 或属性文件 - 多个文件被写入一个目录树中,文件名成为 ‘key’,内容成为 ‘value’。
需要使用 configtree: 前缀,以便 Spring Boot 知道它需要将所有文件作为属性公开
示例:
Kubernetes 已经挂载的 volume
1 | etc/ |
要导入这些属性,你可以在你的 application.properties 或 application.yaml 文件中添加以下内容。spring.config.import=optional:configtree:/etc/config/
属性占位符和通配符
- 属性占位符:${app.name}
- 通配符:*
多文档文件
对于 application.yaml 文件,使用标准的 YAML 多文档语法。 三个连续的连字符(—-)代表一个文件的结束,和下一个文件的开始。
示例:
1 | spring: |
激活属性
你可以使用 spring.config.activation.* 有条件地激活一个属性文件。
属性:
- on-profile:一个必须与之匹配的配置文件表达式,以使文件处于活动状态
- on-cloud-platform:云平台状态下有效
示例:
1 | myprop=always-set |
配置随机值
示例:
1 | my.secret=${random.value} |
类型安全的配置属性
JavaBean 属性绑定
示例:
1 | import java.net.InetAddress; |
前面的 POJO 定义了以下属性。
my.service.enabled,默认值为
false。my.service.remote-address,其类型可由
String强制提供。my.service.security.username,有一个嵌套的 security 对象,其名称由该属性的名称决定。 特别是,那里完全没有使用类型,可以是 SecurityProperties。
my.service.security.password.
my.service.security.role,有一个 String 的集合,默认为 USER。
构造函数绑定
示例:
1 | import java.net.InetAddress; |
Profiles
Spring Profiles 提供了一种方法来隔离你的应用程序配置的一部分,并使其仅在某些环境中可用。 任何 @Component、@Configuration 或 @ConfigurationProperties 都可以用 @Profile 标记,以限制它的加载时机
示例:
1 | import org.springframework.context.annotation.Configuration; |