疯狂 Spring Boot 终极讲义 - 李刚
疯狂 Spring Boot 终极讲义 - 李刚
程序员朱永胜元数据
[!abstract] 疯狂 Spring Boot 终极讲义
- 书名:疯狂 Spring Boot 终极讲义
- 作者:李刚
- 简介:《疯狂 Spring Boot 终极讲义》不是一本介绍类似于 @PathVariable、@MatrixVariable、@RequestBody、@ResponseBody 这些基础注解的图书,它是真正讲解 Spring Boot 的图书。Spring Boot 的核心是什么?它的核心就是自动配置,以及以自动配置为基础与大量第三方后端技术进行整合。因此学习 Spring Boot 应该重点关注的就是它为整合各种框架所提供的自动配置,包括 Spring Boot 如何整合各种前端框架,如 Spring MVC、Spring WebFlux;Spring Boot 如何整合各种持久层技术,如 Spring Data、MyBatis、Hibernate/JPA、R2DBC、jOOQ 等;Spring Boot 如何整合 NoSQL 技术,如 Redis、MongoDB、Neo4j、Cassandra、Solr、Elasticsearch 等;Spring Boot 如何整合各种消息组件,如 ActiveMQ、Artemis、RabbitMQ、Kafka 等;Spring Boot 如何整合各种缓存机制,如 JCache、EhCache、Redis、Hazelcast 等;Spring Boot 如何整合各种安全框架,如 Spring Security、Shiro 等,这些都只是 Spring Boot 整合的典型内容。本书的作用就是带你彻底掌握 Spring Boot 官方手册中所整合的各种技术,而且本书会讲清楚 Spring Boot 和 Spring 框架的关系,带着你揭开 Spring Boot 的核心:自动配置的面纱,领着你剖析 Spring Boot 自动配置的源代码实现,然后以此为基础,详细讲解 Spring Boot 如何整合各种 Java 后端技术。在掌握了本书知识之后,你不仅能轻松看懂 Spring Boot 官方手册(其实无须再看了),而且真正掌握了 Spring Boot 的大成,并通过 Spring Boot 的整合触类旁通地掌握各种 Java 后端技术。本书提供了读者答疑交流群,读者可通过扫描本书封面上的二维码,按照指引加入读者答疑交流群。
- 出版时间:2021-06-01 00:00:00
- ISBN:9787121413711
- 分类:计算机 - 计算机综合
- 出版社:电子工业出版社
- PC 地址:https://weread.qq.com/web/reader/dd132320813ab7c85g01622e
高亮划线
1.2 第一个 Spring Boot 应用
📌 查看 @SpringBootApplication 注解的源代码,可以看到如下内容:[插图] 再打开上面 @SpringBootConfiguration 注解的源代码,可以看到如下内容:[插图] 通过该源代码可以看到,其实 @SpringBootConfiguration 就是 @Configuration。由此可见,@SpringBootApplication 注解相当于以下 3 个注解的组合版。➢@Configuration:该注解修饰的类将作为 Java 配置类。➢@EnableAutoConfiguration:启用自动配置。➢@ComponentScan:指定 “ 零配置 “ 时扫描哪些包及其子包下的 Bean。可见 @SpringBootConfiguration 注解只是一个 “ 快捷方式 “,它同时启用了 3 个注解,从而完成了 3 个功能:➢ 将被修饰的类变成 Java 配置类。➢ 启用自动配置。➢ 定义了 Spring 容器扫描 Bean 类的包及其子包。
⏱ 2023-06-14 06:11:47 ^3300056376-7-14825-15850
2.1 SpringApplication 与 Spring 容器
📌 如果希望 Spring Boot 能加载其他配置类或者扫描其他包下的配置类或 Bean 组件,则可使用如下两个注解。➢@Import:该注解显式指定 Spring Boot 要加载的配置类。➢@ComponentScan:该注解指定 Spring Boot 扫描指定包及其子包下所有的配置类或 Bean 组件。如果项目不可避免地要用到 XML 配置文件,则可用 @ImportResource 注解来导入 XML 配置文件。注意 @Import、@ComponentScan 和 @ImportResource 都是 Spring 框架提供的注解,因此这些内容其实属于 Spring 框架的基础内容。
⏱ 2023-06-14 06:23:11 ^3300056376-12-1127-1556
📌 如果想关闭启动信息的日志,则可将如下属性设为 false。[插图] 上面的配置也会关闭应用程序的活动 Profile 的日志。
⏱ 2023-06-14 06:42:28 ^3300056376-12-5387-5664
📌 比如通过 JAR 包来运行 Spring Boot 应用,则可通过 “–debug” 选项来开启 debug 属性。例如如下命令:[插图]
⏱ 2023-06-14 06:43:25 ^3300056376-12-6288-6374
📌 上面失败分析器的 analyze() 方法返回了一个 FailureAnalysis 对象,表明该失败分析器会对 BindException 进行分析。FailureAnalysis 的本质就是包装三个信息。➢ description:失败的描述信息。第一个构造参数。➢ action:对该失败的修复建议。第二个构造参数。➢ cause:导致失败的异常。第三个构造参数。
⏱ 2023-06-14 06:45:20 ^3300056376-12-8035-8289
📌 自定义失败分析器需要在 META-INF/spring.factories 文件中注册,首先在项目的 resources 目录下创建 META-INF 文件夹(注意大小写和短横线),然后在 META-INF 文件夹内创建 spring.factories 文件,该文件的内容如下:[插图] 上面代码将 org.crazyit.app.MyAnalyzer 类注册为自定义的失败分析器。
⏱ 2023-06-14 06:45:02 ^3300056376-12-8314-8711
📌 要将 Spring 容器设为延迟初始化,有如下三种方式。➢ 调用 SpringApplicationBuilder 对象的 lazyInitialization(true) 方法。➢ 调用 SpringApplication 对象的 setLazyInitialization(true) 方法。➢ 在 application.properties 文件中配置如下代码:[插图] 启用延迟初始化之后,Spring 容器将不会预初始化 Bean,而是等到程序需要调用 Bean 的方法时才执行初始化,因此可降低 Spring Boot 应用的启动时间。
⏱ 2023-06-14 20:45:34 ^3300056376-12-9305-9854
📌 启用延迟初始化主要有如下缺点:➢ 在 Web 应用中,很多与 Web 相关的 Bean 要等到 HTTP 请求第一次到来时才会初始化,因此会降低第一次处理 HTTP 请求的响应效率。➢ Bean 错误被延迟发现。由于延迟初始化的缘故,有些 Bean 的配置可能存在错误,但应用启动时并不会报错,只有等到应用要用到这个配置错误的 Bean 时,程序才会报错,这样就延迟了发现错误的时机。➢ 运行过程中的内存紧张。由于应用启动时并未初始化程序所需的全部 Bean,随着应用程序的运行,当应用中所有的 Bean 初始化完成后,可能就会造成运行时内存紧张。为了避免出现这个问题,可以在延迟初始化之前对 JVM 的堆内存进行微调。
⏱ 2023-06-14 20:46:05 ^3300056376-12-9879-10246
📌 如果要关闭该 Banner,则可通过 application.properties 文件中的 spring.main.banner-mode 属性进行设置。该属性支持如下三个属性值。➢ console:在控制台输出 Banner。➢ log:在日志文件中输出 Banner。➢ off:彻底关闭 Banner。
⏱ 2023-06-14 20:46:31 ^3300056376-12-10468-10690
📌 在类加载路径下添加一个 banner.txt 文件或设置 spring.banner.location,即可指定自定义 Banner 文件的位置;Spring Boot 默认使用 UTF-8 字符集来读取该 Banner 文件的内容,如果要改变读取该文件的字符集,则可在 application.properties 文件中设置如下属性:[插图] 上面的属性设置表示使用 GBK 字符集来读取 Banner 文件的内容。此外,Spring Boot 还允许使用图片文件来添加 Banner,只要在类加载路径下添加一个 banner.gif`banner.jpg 或 banner.png 图片文件,或者通过 spring.banner.image.location 属性设置图片 Banner 的加载路径,Spring Boot 就会自动把该图片转换为字符画 (ASCII art) 形式,并作为应用程序的 Banner 显示。
⏱ 2023-06-14 20:47:03 ^3300056376-12-10743-11369
📌 当图片 Banner 和文本 Banner 同时存在时,Spring Boot 将会先显示图片 Banner 对应的字符画,然后再显示文本 Banner 的内容。
⏱ 2023-06-14 20:47:22 ^3300056376-12-11394-11466
📌 除了直接调用构造器来创建 SpringApplication 对象,Spring Boot 还提供了 SpringApplicationBuilder 工具类,通过该工具类能以流式 API 创建 SpringApplication,并启动 Spring Boot 应用。此外,SpringApplicationBuilder 还提供了如下方法来加载配置文件。➢ sources(Class﹤?﹥…sources):为应用添加配置类。➢ child(Class﹤?﹥…sources):为当前容器添加子容器配置类。➢ parent(Class﹤?﹥…sources):为当前容器添加父容器配置类。从这些方法可以看出,使用 SpringApplicationBuilder 可以构建 ApplicationContext 的层次结构(让 Spring 容器具有父子关系)
⏱ 2023-06-14 20:49:30 ^3300056376-12-14551-15049
📌 让多个 Spring 容器具有层次结构具有很多好处。比如,由于子容器是由父容器负责加载的,因此子容器中的 Bean 可访问父容器中的 Bean,但父容器中的 Bean 不能访问子容器中的 Bean。
⏱ 2023-06-14 20:49:47 ^3300056376-12-15720-15812
📌 采用传统方式注册的事件监听器都是部署在 ApplicationContext 容器中的,它们必须等到容器被创建之后才会出现,而 SpringApplication 的有些事件是在容器被创建之前被触发的。
⏱ 2023-06-14 20:51:54 ^3300056376-12-16109-16206
📌 为了监听 SpringApplication 触发的事件,SpringApplication 提供了如下方式来注册事件监听器。➢ 调用 SpringApplication 的 addListeners() 方法或 SpringApplicationBuilder 的 listeners() 方法添加事件监听器。➢ 使用 META-INF/spring.factories 文件来配置事件监听器。在该文件中添加如下代码即可注册事件监听器:org.springframework.context.ApplicationListener=org.crazyit.app.MyListener
⏱ 2023-06-14 20:51:31 ^3300056376-12-16231-16587
📌 当 Spring Boot 应用启动时,SpringApplication 会依次触发如下事件:[插图] 在应用刚刚开始
还未进行任何处理之时,触发 ApplicationStartingEvent 事件,除非监听器和初始化器注册失败。[插图]当 ApplicationContext 要使用的 Environment 已经确定,但 ApplicationContext 还未被创建之时,触发 ApplicationEnvironmentPreparedEvent 事件。[插图]当 ApplicationContext 准备完成且初始化器 (ApplicationContextInitializer) 已被调用,但未加载任何 Bean 定义之前,触发 ApplicationContextInitializedEvent 事件。[插图]在所有 Bean 定义被加载之后
Spring 容器刷新之前,触发 ApplicationPreparedEvent 事件。在 Spring 容器刷新之后,ApplicationRunnerCommandLineRunner 的接口方法被调用之前,触发 ApplicationStartedEvent 事件。[插图] 当应用程序的 LivenessState 状态变成 CORRECT,表明应用程序进入 live 状态时,触发 AvailabilityChangeEvent 事件。[插图]当所有 ApplicationRunner
CommandLineRunner 的接口方法被调用完成后,触发 ApplicationReadyEvent 事件。[插图] 提示:ApplicationRunner 和 CommandLineRunner 是 Spring Boot 提供的两个回调接口,2.1.8 节会详细介绍。[插图] 当应用程序的 ReadinessState 状态变成 ACCEPTING_TRAFFIC,表明应用程序准备接受服务请求时,触发 AvailabilityChangeEvent 事件。[插图] 如果启动遇到异常,则触发 ApplicationFailedEvent 事件。
⏱ 2023-06-14 20:53:33 ^3300056376-12-16612-19094
📌 上面列出的都是绑定到 SpringApplication 的 SpringApplicationEvent 事件。此外,还会在 ApplicationPreparedEvent 事件与 ApplicationStartedEvent 事件之间触发如下两个容器事件:➢ Web 服务器初始化完成后触发 WebServerInitializeEvent 事件;如果使用 Servlet Web 服务器,则触发 ServletWebServerInitializedEvent 事件;如果使用反应式 Web 服务器,则触发 ReactiveWebServerInitializedEvent 事件。➢ 在刷新 ApplicationContext 时触发 ContextRefreshedEvent 事件。
⏱ 2023-06-14 20:54:21 ^3300056376-12-19119-19500
📌 由于事件监听器采用同一个线程来执行,因此不应该在事件监听器中执行某些耗时的操作;如果确实需要完成某些耗时的操作,则建议使用 ApplicationRunner 或 CommandLineRunner 接口。
⏱ 2023-06-14 20:54:58 ^3300056376-12-19683-19783
📌 由于上面这些事件都是通过 Spring 框架的事件机制来发布的,这种机制会保证子容器中触发的事件也会自动触发父容器中的监听器。因此,如果应用程序采用了层次结构的容器(通过 SpringApplicationBuilder 启动 Spring Boot 应用时,可使用层次结构的容器),那么事件监听器就有可能接收到同一类型事件的多个实例—它们来自不同的容器。
⏱ 2023-06-14 20:55:18 ^3300056376-12-19808-19981
📌 为了让事件监听器能区分事件到底来自哪个容器,可以用事件监听器依赖注入的容器与事件来自的容器进行比较;为了将容器依赖注入事件监听器,可通过如下两种方式。➢ 接口注入:让事件监听器实现 ApplicationContextAware 接口,Spring 容器将会被注入监听器。提示:ApplicationContextAware 是 Spring 接口注入的基础内容,如果要了解如何利用该接口完成接口注入,请参考《轻量级 Java Web 企业应用实战》的 4.4 节。➢ 普通注入:如果事件监听器是容器中的 Bean,则可直接使用 @Autowired 注解来完成依赖注入。除了监听器,Spring Boot 还提供了 ApplicationContextInitializer 对 Spring 容器执行初始化。ApplicationContextInitializer 接口的实现类被称为 “ 初始化器 “,该接口的实现类必然实现其中的 initialize(C ctx) 方法,通过该方法的参数也可对 Spring 容器进行设置。有了 ApplicationContextInitializer 实现类之后,接下来可通过如下方式来注册初始化器。➢ 调用 SpringApplication 的 addInitializers() 方法或 SpringApplicationBuilder 的 initializers() 方法添加初始化器。➢ 使用 META-INF/spring.factories 文件来配置初始化器。在该文件中添加如下代码即可注册初始化器:[插图]
⏱ 2023-06-14 20:58:14 ^3300056376-12-20006-20912
📌 如果想在 Environment 对象创建之后 `Spring 容器刷新之前对 Environment 对象(配置环境)进行定制,Spring Boot 提供了配置环境后处理器—实现 EnvironmentPostProcessor 接口的类被称为” 配置环境后处理器”
⏱ 2023-06-14 20:58:43 ^3300056376-12-21193-21318
📌 @ValueSource 注解必须等到 Spring 容器刷新之后才会得到处理,此时去读取 @ValueSource 注解所加载的资源,再添加到 Environment 中已经太迟了
⏱ 2023-06-14 20:59:27 ^3300056376-12-21660-21744
📌 有了 ApplicationContextInitializer 实现类之后,可通过 META-INF/spring.factories 文件来注册配置环境后处理器。例如如下代码:[插图]
⏱ 2023-06-14 20:59:59 ^3300056376-12-21770-21884
📌 在 SpringApplication 的 run() 方法(应用启动)完成之前,ApplicationRunner 和 CommandLineRunner 实现类会自动调用接口中的 run() 方法
⏱ 2023-06-14 22:15:48 ^3300056376-12-27276-27369
📌 ApplicationRunner 接口与 CommandLineRunner 接口的功能基本是相同的。总之,随便用哪个区别并不大,只不过它们获取 SpringApplication 运行参数的方式不同而已
⏱ 2023-06-14 22:16:48 ^3300056376-12-27842-27941
📌 以双短横线开头的选项参数会覆盖 application.properties 等配置文件中的属性
⏱ 2023-06-14 22:18:30 ^3300056376-12-30094-30140
📌 SpringApplication 会按如下规则来创建 ApplicationContext 容器:➢ 如果为项目添加了 Spring MVC 依赖,则使用 AnnotationConfigServletWebServerApplication-Context 作为 Spring 容器。➢ 如果为项目添加了 Spring WebFlux 依赖,没有添加 Spring MVC 依赖,则使用 AnnotationConfigReactiveWebServerApplicationContext 作为 Spring 容器。➢ 否则,使用 AnnotationConfigApplicationContext 作为 Spring 容器。
⏱ 2023-06-14 22:19:24 ^3300056376-12-30562-30935
📌 当为项目同时添加了 Spring MVC 依赖和 Spring WebFlux 依赖时,依然使用 AnnotationConfig-ServletWebServerApplicationContext 作为 Spring 容器
⏱ 2023-06-14 22:19:43 ^3300056376-12-30960-31065
📌 更现实的做法是,调用 SpringApplication 的 setWebApplicationType() 方法来设置 Spring 容器的类型,该方法接受如下 WebApplicationType 类型的枚举值。➢ NONE:运行非 Web 应用,不启动内嵌的 Web 服务器。➢ REACTIVE:运行反应式 Web 应用,启动内嵌的反应式 Web 服务器。➢ SERVLET:运行基于 Servlet 的 Web 应用,启用内嵌的 Servlet Web 服务器。
⏱ 2023-06-14 22:20:30 ^3300056376-12-31246-31535
2.2 外部配置源
📌 获取这些外部化的属性主要有如下几种方式:➢ 使用 @Value 注解将属性值注入任何 Bean 组件。➢ 使用 Spring 的 Environment 抽象层进行访问。➢ 使用 @ConfigurationProperties 注解将一批特定属性绑定到指定 Java 对象。
⏱ 2023-06-14 22:23:03 ^3300056376-13-755-956
📌 2.2.1 配置源的加载顺序与优先级
各种外部配置源的加载顺序如下,所有先加载的配置源都可能被后加载的配置源覆盖,因此可认为后加载的配置源的优先级更高。
⏱ 2023-06-14 22:25:35 ^3300056376-13-1074
📌 如果不希望将命令行的选项属性添加到配置环境中,则可调用 SpringApplication 对象的 setAddCommandLineProperties(false) 方法来禁用该功能。
⏱ 2023-06-14 22:26:25 ^3300056376-13-5133-5224
📌 application.properties(包括 application.yml)也有几个不同的来源,它们按如下顺序加载:[插图]JAR 包内的 application.properties(或 application.yml)。[插图]JAR 包内的 application-{profile}.properties(或 application-{profile}.yml),这是特定的 Profile 对应的配置文件。[插图]JAR 包外临时指定的 application.properties(或 application.yml)。[插图]JAR 包外临时指定的 application-{profile}.properties(或 application-{profile}.yml)
⏱ 2023-06-15 07:05:44 ^3300056376-13-6320-7348
📌 如果 YAML 配置属性值包含多个列表项,那么它将被自动转换为[index] 的形式。例如如下配置:[插图] 它将被转换为如下属性:[插图]
⏱ 2023-06-15 07:09:42 ^3300056376-13-12543-12852
📌 @PropertySource 和 @TestPropertySource 这两个注解都只能加载属性文件,不能加载 YAML 文件,这是 YAML 文件的局限之一
⏱ 2023-06-15 07:10:31 ^3300056376-13-13477-13551
📌 在默认情况下,Spring Boot 会自动按如下顺序加载默认的配置文件,后加载的属性文件可以覆盖先加载的属性文件,因此可认为后加载的属性文件具有更高的优先级。[插图] 类加载路径的根路径。[插图] 类加载路径下的 /config 子目录。[插图] 当前路径。[插图] 当前路径下的 /config 子目录。[插图] 当前路径下 /config 子目录的任意直接子目录,如 /config/abc/`/config/xyz/ 等。
⏱ 2023-06-15 07:13:13 ^3300056376-13-18442-19514
📌 如果想改变这种默认行为,Spring Boot 可通过如下系统属性(或环境变量,或命令行参数)来改变配置文件的位置。➢ spring.config.name:改变配置文件的文件名,默认是 application。如果用 OS 环境变量来设置,则该属性对应于 SPRING_CONFIG_NAME 环境变量名。➢ spring.config.location:改变配置文件的加载路径。如果用 OS 环境变量来设置,则该属性对应于 SPRING_CONFIG_LOCATION 环境变量名。➢ spring.config.additional-location:添加配置文件的加载路径,不会覆盖原有的配置文件的加载路径。注意不要尝试使用 Spring Boot 配置属性来设置 spring.config.name、spring.config.location、spring.config.additional-location 属性,因为这几个属性的加载时机非常早,所以只能通过系统环境变量、系统属性或命令行参数来设置。通过 spring.config.location 或 spring.config.additional-location 属性指定的加载路径是有先后顺序的,后面路径中的配置文件将会后加载,因此它具有更高的优先级。
⏱ 2023-06-15 07:14:20 ^3300056376-13-19539-20266
📌 在配置加载路径时,使用通配符有如下限制:➢ 通配符只能在外部路径中使用,例如 file:前缀就表示使用文件系统的当前路径;classpath:前缀的路径不能使用通配符。➢ 每个加载路径只能在最后面使用一个通配符,不能写成 file:.///,这太荒唐了,只能写成如 file:/fkjava/*/ 的形式,这表示当前路径下 /fkjava 子目录的任意直接子目录。
⏱ 2023-06-15 07:16:08 ^3300056376-13-22851-23079
📌 在 Spring 容器刷新之后,Spring Boot 还可使用如下方式导入额外的配置文件:➢ 使用 @PropertySource 注解导入额外的属性文件。➢ 使用 spring.config.import 属性导入额外的配置文件(包括属性文件和 YAML 文件)。
⏱ 2023-06-15 07:42:49 ^3300056376-13-25007-25182
📌 在配置文件中可通过占位符 (${}) 的方式来引用已定义的属性,或者引用其他配置源(如系统属性
环境变量
命令参数等)配置的属性
⏱ 2023-06-15 07:46:10 ^3300056376-13-27268-27330
📌 有些特殊的时候(比如出于测试的需要),需要为应用配置各种随机值,包括随机整数 `UUID 等,它们都可通过 Spring Boot 的 RandomValuePropertySource 来配置。
⏱ 2023-06-15 08:05:46 ^3300056376-13-31855-31947
2.3 类型安全的绑定
📌 @ConfigurationProperties 注解有两种主要用法。➢ 修饰属性处理类:当 @ConfigurationProperties 注解修饰的类被部署为容器中的 Bean 时,该注解指定的属性将会被注入该 Bean 的属性。因此,将 @ConfigurationProperties 注解修饰的类称为” 属性处理类”。➢ 修饰 @Bean 注解修饰的方法:使用 @Bean 修饰的方法将会配置一个容器中的 Bean,而 @ConfigurationProperties 注解指定的属性将会被注入该 Bean 的属性。在使用 @ConfigurationProperties 注解时可指定如下属性。
⏱ 2023-07-03 02:08:11 ^3300056376-14-639-999
📌 尽量为 @ConfigurationProperties 修饰的类添加 spring-boot-configuration-processor 依赖,这样 IntelliJ IDEA 能提供更友好的编辑帮助。
⏱ 2023-07-03 02:14:17 ^3300056376-14-2738-2836
📌 Spring Boot 并不会自动启用 @ConfigurationProperties 注解。让 Spring Boot 启用该注解有如下方式:➢ 为 @ConfigurationProperties 注解修饰的类添加 @Component 注解。➢ 将 @ConfigurationProperties 注解修饰的类显式配置成容器中的 Bean。➢ 使用 @EnableConfigurationProperties 注解,该注解可显式指定一个或多个属性处理类,Spring Boot 将会启用这些属性处理类上的 @ConfigurationProperties 注解。➢ 使用 @ConfigurationPropertiesScan 注解,该注解可指定启用一个或多个包及其子包下所有带 @ConfigurationProperties 注解的类。
⏱ 2023-07-03 02:14:53 ^3300056376-14-2868-3326
📌 属性处理类同样也支持用构造器来完成属性值注入,只要额外使用 @ConstructorBinding 注解修饰用于执行属性值注入的构造器即可。如果该类仅包含一个构造器,则可直接用该注解修饰属性处理类。值得注意的是,如果使用构造器来完成属性值注入,则要求使用 @EnableConfigurationProperties 注解或 @ConfigurationPropertiesScan 注解来启用 @ConfigurationProperties 注解
⏱ 2023-07-03 02:15:55 ^3300056376-14-4909-5151
📌 在 *.properties 文件中配置 List 有两种方式:简单地使用英文逗号隔开的多个值(如前面 setter 例子所示),或者用标准的方括号语法来配置 List。
⏱ 2023-07-03 02:18:09 ^3300056376-14-6958-7036
📌 在 *.yml 文件中配置 List 也有两种方式:以短横线开头(如上面 constructor 例子所示),或者简单地使用英文逗号隔开的多个值来配置 List。
⏱ 2023-07-03 02:18:22 ^3300056376-14-7063-7137
📌 从本质上看,@ConfigurationProperties 注解的作用就是驱动被修饰的 @Bean 方法所配置的对象调用相应的 setter 方法,比如 @ConfigurationProperties 注解读取到 title 属性,它就会驱动 Spring Boot 以反射方式执行 @Bean 方法所配置的对象的 setTitle() 方法,并将 title 属性值作为 setTitle() 方法的参数。
⏱ 2023-07-03 02:28:00 ^3300056376-14-9697-9886
📌 由于 @Value 是 Spring 容器的核心特征,因此该注解可以支持 SpEL(Spring 表达式语言),而 @ConfigurationProperties 则不支持该功能
⏱ 2023-07-03 02:28:41 ^3300056376-14-10992-11074
📌 [插图]
⏱ 2023-07-03 02:29:02 ^3300056376-14-11235-11236
📌 如果希望 Spring Boot 忽略转换失败的配置属性值,则可将 @ConfigurationProperties 注解的 ignoreInvalidFields 属性设置为 true(它的默认值为 false)
⏱ 2023-07-03 02:30:05 ^3300056376-14-12061-12161
📌 在定义 Duration 类型的配置属性时,如果直接定义整数值,则该整数值将被当成多少毫秒处理,除非在该属性上使用 @DurationUnit 注解指定了默认的时间单位。在配置属性值时可指定如下时间单位。➢ ns:纳秒。➢ μs:微秒。➢ ms:毫秒。➢ s:秒。➢ m:分钟。➢ h:小时。➢ d:天。
⏱ 2023-07-03 02:30:53 ^3300056376-14-12476-12800
📌 在定义 Period 类型的配置属性时,如果直接定义整数值,则该整数值将被当成多少天处理,除非在该属性上使用 @PeriodUnit 注解指定了默认的时间单位。在配置属性值时可指定如下时间单位。➢ y:年。➢ m:月。➢ w:星期。➢ d:天。
⏱ 2023-07-03 02:30:37 ^3300056376-14-12825-13044
📌 在定义 DataSize 类型的配置属性时,如果直接定义整数值,该整数值将被当成多少字节处理,除非在该属性上使用 @DataSizeUnit 注解指定了默认的数据单位。在配置属性值时可指定如下数据单位。➢ B:字节。➢ KB:千字节。➢ MB:兆字节。➢ GB:吉字节。➢ TB:太字节。
⏱ 2023-07-03 02:31:04 ^3300056376-14-13115-13380
📌 @ConfigurationProperties 的数据校验是基于 JSR 303 的,因此在执行数据校验之前,必须先添加 JSR 303 规范的依赖以及 JSR 303 实现的依赖。Spring Boot 为数据校验提供了 spring-boot-starter-validation 依赖库,它已经包含了 JSR 303 规范和实现的依赖,因此只要在 pom.xml 文件中添加如下依赖库即可。
⏱ 2023-07-03 02:32:00 ^3300056376-14-15022-15210
2.4 Profile
📌 使用 @Profile 注解修饰 @Component
@Configuration
@ConfigurationProperties 等注解修饰的类,这限制了这些类仅对特定的 Profile 有效。
⏱ 2023-07-03 02:33:28 ^3300056376-15-1140-1234
📌 通过配置文件的文件名限制 Profile。比如 application-dev.properties(或 application-dev.yml)文件限制了仅对 dev Profile 有效;application-test.properties(或 application-test.yml)文件限制了仅对 test Profile 有效。
⏱ 2023-07-03 02:33:39 ^3300056376-15-1261-1424
📌 在配置文件中使用特定语法限制某些属性仅对特定的 Profile 有效。这种特殊的配置文件被称为” 多 Profile 配置文件”。
⏱ 2023-07-03 02:33:53 ^3300056376-15-1451-1511
📌 对于 @ConfigurationProperties 类有一点需要说明:如果 @ConfigurationProperties 类是通过 @EnableConfigurationProperties 注解来启用的,而不是通过扫描方式(用 @ConfigurationPropertiesScan 注解)来启用的,则需要在 @EnableConfigurationProperties 注解所在的 @Configuration 类上使用 @Profile 注解。对于以扫描方式启用的 @ConfigurationProperties 注解,则可在 @ConfigurationProperties 类本身上指定 @Profile 注解。
⏱ 2023-07-03 02:34:37 ^3300056376-15-1536-1838
📌 通过命令行参数指定的 spring.profiles.active 属性会覆盖前面几种方式指定的该属性。
⏱ 2023-07-03 02:36:11 ^3300056376-15-4971-5021
📌 添加新 Profile 可通过如下方式进行:➢ 使用 spring.profiles.include 属性,与 spring.profiles.active 不同,include 是添加 Profile,而 active 是指定激活新的活动 Profile。➢ 调用 SpringApplication 的 setAdditionalProfiles() 方法来添加新的活动 Profile。下面对上一个示例略做修改,本例再次添加一份与新的 Profile 相关的配置文件。
⏱ 2023-07-03 02:37:31 ^3300056376-15-7331-7600
📌 在属性文件中通过如下配置片段来配置一个组:[插图] 上面配置指定 banner 和 server 都属于 prod Profile 组,因此,如果程序设置 prod 作为活动 Profile,那么 banner 和 server 两个 Profile 的配置也会被加载。
⏱ 2023-07-03 02:38:46 ^3300056376-15-9533-9870
📌 对于 list 属性而言,后配置的 List 集合直接替换先配置的 List 集合
⏱ 2023-07-03 02:40:59 ^3300056376-15-14995-15033
📌 对于 map 属性而言,后配置的 Map 的 key-value 对将会被添加到先配置的 Map 中
⏱ 2023-07-03 02:41:08 ^3300056376-15-15094-15136
📌 当配置文件被分割成多个配置之后,接下来可通过如下属性指定” 条件性” 生效。➢ spring.config.activate.on-profile:指定此行配置以下的配置仅当指定的 Profile 激活时才有效。该属性也支持使用取反运算符(!),比如”!dev” 表示非 dev Profile 时有效。➢ spring.config.activate.on-cloud-platform:指定此行配置以下的配置仅当处于指定的云平台上时才有效。比如配置片段:[插图] 上面的配置片段配置了 myprop 属性为 always-set,这个属性总是有效的。此外,还配置了 otherprop 属性为 sometimes-set,只有当 prod Profile 处于活动状态时,该属性才有效。再比如配置片段:[插图] 上面的配置片段配置了 myprop 属性为 always-set,这个属性总是有效的。此外,还配置了 otherprop 属性为 sometimes-set,只有当该应用被部署在 K8s 云平台时,该属性才有效。
⏱ 2023-07-03 02:42:17 ^3300056376-15-15905-16886
2.5 日志配置
📌,spring-boot-starter-logging.jar 依赖如下三个 JAR 包。➢ logback-classic.jar:它传递依赖于 logback-core.jar 和 slf4j-api.jar。➢ log4j-to-slf4j.jar:它传递依赖于 log4j-api.jar 和 slf4j-api.jar。➢ jul-to-slf4j.jar:它传递依赖于 slf4j-api.jar。
⏱ 2023-07-03 02:43:19 ^3300056376-16-1053-1324
📌 Spring Boot 默认使用 SLF4J+Logback 的日志组合,其中 SLF4J 作为日志门面(应用程序输出日志时也应该面向该 API),Logback 作为日志实现
⏱ 2023-07-03 02:44:30 ^3300056376-16-1626-1707
📌 当把 Spring Boot 应用部署到 Web 服务器或应用服务器上时,JUL 生成的日志将不会被路由到 Spring Boot 应用的日志中,这是为了避免将服务器或部署在服务器上的其他应用程序的日志也路由到 Spring Boot 应用的日志中,否则会造成日志的混乱
⏱ 2023-07-03 02:45:55 ^3300056376-16-2340-2466
📌 当把 Spring Boot 应用部署到 Web 服务器或应用服务器上时,JUL 生成的日志将不再被路由到 Spring Boot 应用的日志中
⏱ 2023-07-03 02:46:04 ^3300056376-16-2801-2866
📌 Spring Boot 怎么配置才能让 MyBatis 输出它执行的 SQL 语句呢?非常简单:[插图]
⏱ 2023-07-03 22:45:06 ^3300056376-16-11380-11451
📌 Spring Boot 怎么配置才能看到 Redis 的详细执行过程?非常简单:[插图]Spring Boot 整合 Redis 默认使用 Lettuce 依赖,而 io.lettuce.core 就是 Lettuce 组件核心 API 所在的包
⏱ 2023-07-03 22:44:58 ^3300056376-16-11651-11979
📌 Spring Boot 怎么配置才能看到 MongoDB 的详细执行过程?非常简单:[插图]
⏱ 2023-07-03 22:45:15 ^3300056376-16-12010-12077
📌 Spring Boot 允许通过 spring.output.ansi.enabled 属性设置是否用不同颜色来区分不同级别的日志,该属性支持如下属性值。➢ always:总是启用。➢ detect:自动检查。如果控制台支持 ANSI 颜色特性,则启用。这是默认值。➢ never:不启用。
⏱ 2023-07-03 22:46:05 ^3300056376-16-12698-12913
📌 Spring Boot 默认只将日志输出到控制台,不输出到文件。如果要将日志输出到文件,则可为 Spring Boot 设置如下两个属性之一。➢ logging.file:设置日志文件。➢ logging.path:设置日志文件的目录。使用默认的 spring.log 作为文件名。
⏱ 2023-07-03 22:47:48 ^3300056376-16-14867-15054
📌 如果想改变 Spring Boot 的底层日志实现(放弃 Logback 作为底层日志实现),则只需要如下两步。[插图] 去掉 Logback 依赖库,添加新日志实现的依赖库。[插图] 在类加载路径的根路径下为新日志实现提供对应的配置文件。
⏱ 2023-07-03 22:51:25 ^3300056376-16-20524-20986
📌 Spring Boot 推荐使用带 -spring 的配置文件,比如对于 Logback 日志系统,使用 logback-spring.xml 作为配置文件比用 logback.xml 文件更好。此外,Spring Boot 建议尽量避免使用 JUL 日志系统实现,因为 JUL 的类加载机制会导致一些问题。
⏱ 2023-07-03 22:52:32 ^3300056376-16-21950-22090
📌 如果打算在日志属性中使用占位符,请记住要用 Spring Boot 语法,而不是底层日志框架的语法。尤其是使用 Logback 时,应该使用英文冒号(:) 作为属性名和默认值的分隔符,而不是使用冒号减号(:-)。
⏱ 2023-07-03 22:52:53 ^3300056376-16-22630-22732
📌 若要使用 Logback 的扩展功能,就不能使用 logback.xml 配置文件,因为该配置文件的加载时机太早了,Spring Boot 的其他基础功能还没来得及加载。
⏱ 2023-07-03 22:55:14 ^3300056376-16-26707-26787
📌 Spring Boot 对 Logback 的扩展主要体现在如下两个方面。➢ 与 Profile 相关的日志。➢ 环境属性。
⏱ 2023-07-03 22:55:19 ^3300056376-16-26812-26919
2.6 自动配置概述
📌 Spring Boot 自动配置通常有一个原则(只是通常,但也有特例):只有当容器中不存在特定类型的 Bean 或特定 Bean 时,Spring Boot 自动配置才会配置该类型的 Bean 或特定 Bean。
⏱ 2023-07-03 22:57:23 ^3300056376-17-1112-1209
2.7 创建自己的自动配置
📌 如果要为自动配置类指定它们的加载顺序,Spring Boot 则提供了如下两个注解。➢@AutoConfigureAfter:指定被修饰的类必须在一个或多个自动配置类加载之后加载。➢@AutoConfigureBefore:指定被修饰的类必须在一个或多个自动配置类加载之前加载。
⏱ 2023-07-03 23:03:30 ^3300056376-18-8404-8592
📌 如果自动配置包中包含多个自动配置类,且要求以特定的顺序来加载这些自动配置类,则可用 @AutoConfigureOrder 注解来修饰它们。@AutoConfigureOrder 注解完全类似于 Spring 框架原有的 @Order 注解,只不过它专门用于修饰自动配置类。
⏱ 2023-07-03 23:03:43 ^3300056376-18-8617-8747
📌 Spring Boot 的自动配置才能执行类似于如下的智能行为。➢ 当 Spring Boot 检测到类加载路径包含某个框架时,会自动配置该框架的基础 Bean。➢ 只有当开发者没配置某些 Bean 时,Spring Boot 才会在容器中自动配置对应的 Bean。➢ 只有当开发者配置了某些属性时,Spring Boot 才会在容器中自动配置对应的 Bean。
⏱ 2023-07-03 23:04:11 ^3300056376-18-9063-9310
📌 Spring Boot 的条件注解可支持如下几类条件。➢ 类条件注解:@ConditionalOnClass
@ConditionalOnMissingClass。➢ Bean 条注解:@Conditional On Missing Bean
@Conditional On Single Candidate@Conditional On Bean
@Conditional On Missing FilterBean。➢ 属性条件注解:@ConditionalOnProperty。➢ 资源条件注解:@ConditionalOnResource。➢ Web 应用条件注解:@ConditionalOnWebApplication@ConditionalOnNotWebApplication
@ConditionalOnWarDeployment。➢ SpEL 表达式条件注解:@ConditionalOnExpression。➢ 特殊条件注解:@ConditionalOnCloudPlatform@ConditionalOnJava
@ConditionalOnJndi`@ConditionalOnRepositoryType。
⏱ 2023-07-03 23:04:39 ^3300056376-18-9340-10032
📌 开发自己的自动配置很简单,其实也就两步:[插图] 使用 @Configuration 和条件注解定义自动配置类。[插图] 在 META-INF/spring.factories 文件中注册自动配置类。
⏱ 2023-07-03 23:09:47 ^3300056376-18-24848-25292
📌 对于第三方 Starter,Spring Boot 建议不要使用 spring-boot-starter-xxx 这种命令方式,因为这种命令方式应该留给 Spring 官方使用。
⏱ 2023-07-03 23:12:07 ^3300056376-18-31831-31914
读书笔记
2.4 Profile
划线评论
📌 使用操作系统的 SPRING_PROFILES_ACTIVE 环境变量指定 ^280435523-7JpS4OLJa
- 💭 指定 profile
- ⏱ 2023-07-03 02:35:44
2.5 日志配置
划线评论
📌 门面类(抽象层):SLF4J
JCL
JBoss Logging。
➢ 日志实现:Log4jLog4j2
Logback`JUL。^280435523-7JpSDQ7yA
- 💭 日志分类
- ⏱ 2023-07-03 02:44:22
划线评论
📌 [插图] ^280435523-7Jr9T3qgT
- 💭 改为 log4j2
- ⏱ 2023-07-03 22:54:21