SpringBoot3基础教程之核心特性
第一部分新手 分为快速入门、web开发、书网文、基础特性、核心原理五个单元;
第二部分进阶 (场景实战)分为Docker快速入门、NoSQL、接口文档、远程调用、消息服务、Web安全、可观测性、AOT共7个单元;
原作者笔记放在语雀:SpringBoot3全栈指南
原作者代码:spring-boot-3: springboot3-示例代码
笔记记录起始:2024.12.3

1.1 Boot3的快速入门:
1.1.1 快速入门:
1)创建项目流程的记忆点:
pom文件依赖导入、主程序创建、编写controller、运行;
pom中还可以包含Springboot应用打包插件 、然后在maven控制中package进行打包、jar包被存储到了target目录中,cmd终端进行java -jar运行jar包;
外部化配置在jar包的同目录下、创建applicationg.properties即可修改端口号等快速配置!
2)特性小结springboot3:
1.简化整合:通过导入相关的场景启动器(starter)拥有写相关的功能;
官方启动器:构建系统 :: Spring Boot 在文档的末尾一共由三个表,包含了主流的第一方场景启动器 ”spring-boot-starter- “。除此之外还有大量的第三方 ” -spring-boot-starter- “ 。
2.简化开发:无需编写配置文件\只需面向业务开发!
3.简化配置:集中式管理配置\ 配置基本由默认值\ 所有配置均在applicaition.properties文件
applicaition.properties文件的配置方法,参考官网的springboot3.4的Appendix下的common Application Properties文档:Common Application Properties :: Spring Boot
4.简化部署:
使用>mvn clean pakage打包成jar包、从cmd终端java -jar 直接打包部署。
5.简化运维:
3) Spring Initializr创建项目:一键创建好项目结构如下,

1.1.2 应用实践的细节分析
1)依赖管理机制与自动配置机制
为什么不写版本号?
答:每个boot项目都已一个父项目spring-boot-starter-parent;
parent的父项目是spring-boot-dependencies;
父项目版本仲裁中心,把所有常见的jar依赖版本都声明好了,比如mysql-connecter-java
如何自定义版本号?直接导入依赖时声明版本即可 或者利用maven的就近原则
第三方的jar包?必须在引入依赖时,声明版本号!
自动配置机制:相较于使用SpirngMVC需要配置的DispathcerServlet等一系列组件配置,使用springboot之后会自动配置好容器中的所有组件。容器中有了什么组件,就有什么功能。
public static void main(String[] args) {
//java10: 局部变量类型的自动推断
var ioc = SpringApplication.run(MainApplication.class, args);
//1、获取容器中所有组件的名字
String[] names = ioc.getBeanDefinitionNames();
//2、挨个遍历:
// dispatcherServlet、beanNameViewResolver、characterEncodingFilter、multipartResolver
// SpringBoot把以前配置的核心组件现在都给我们自动配置好了。
for (String name : names) {
System.out.println(name);
}
}
在主程序中,上述代码可以答应出容器中的所有组件名字!
-
默认的包扫描规则:
由
@SpringbootApplicaition标注的类为主程序类,Springboot只会扫描主程序所在的包及其下面的子包,相当于自动的component-Scan功能。可以使用
@SpringBootConfiguration(scanBasePackages = "com.westsub")完成自定义扫描路径。 -
配置默认值:
配置文件的所有配置项是和某个类的对象值进行一一绑定的。
绑定了配置文件中每一项值的类: 属性类。
比如:
-
ServerProperties绑定了所有Tomcat服务器有关的配置 -
MultipartProperties绑定了所有文件上传相关的配置 -
…参照官方文档:或者参照 绑定的 属性类。
-
-
按需加载的自动配置:
例如,导入
spring-boot-starter-web时, 场景启动器会导入一个spring-boot-starter,然后spring-boot-starter会再导入了一个包spring-boot-autoconfigure。包里面都是各种场景的AutoConfiguration自动配置类。
虽然全场景的自动配置都在spring-boot-autoconfigure这个包,但是不是全都开启的。导入哪个场景就开启哪个自动配置。
自动配置的流程细节梳理:从一到四
一、导入starter-web,web开发场景:

二、主程序 @SpringbootApplication: 如何实现自动配置的?
进入主程序的注解中——>
进入@EnableAutoConfiguration 是开启自动配置的核心注解 ——>
进入@Import(AutoConfigImportSelector.class)——>
找到 Protected AutoConfigurationEntry getAutoConfigurationEntry(AnnatationMetadata)

三、xxxAutoConfiguration 自动配置类:

四、编写业务代码,无需关心底层的系统整合工作

自动配置核心流程的总结如下:
1、导入starter,就会导入autoconfigure包。
2、autoconfigure 包里面 有一个文件 META-INF/spring/**org.springframework.boot.autoconfigure.AutoConfiguration**.imports, 里面指定的所有启动要加载的自动配置类,如今的3.4.0版本boot,有153个配置类
3、@EnableAutoConfiguration 会自动的把上面文件里面写的所有自动配置类都导入进来。xxxAutoConfiguration 是有条件注解进行按需加载
4、xxxAutoConfiguration给容器中导入一堆组件,组件都是从 xxxProperties中提取属性值
5、xxxProperties又是和配置文件进行了绑定
**最终效果:**我们导入starter 并修改.properties 配置文件,就能修改底层行为与项目搭建。
2)如何学好SpringBoot3!!! 以P12学习Redis为例理解
普通开发:导入starter,Controller、Service、Mapper、偶尔修改配置文件
高级开发:自定义组件、自定义配置、自定义starter
核心:三个问好和一个感叹号
- 这个场景自动配置导入了哪些组件,我们能不能Autowired进来使用?
- 能不能通过修改配置改变组件的一些默认参数?
- 需不需要自己完全定义这个组件?
- 场景定制化!
做项目的最佳实践应该如此:
选场景、写配置并改配置文件关键项、分析组件、定制化。

待学习的Redis-starter视频:12.整合Redis为例-理解如何学好SpringBoot_哔哩哔哩_bilibili
1.1.3 核心技能(常用注解、yml文件、日志配置)
全注解驱动的SpringBoot3
1)常用注解:(组件注册、条件注解、属性绑定)
以前需要在xml文件中使用<bean> </bean> 的方式进行bean的注册,但是在Springboot3中改为在Config包的Appconfig类上标注@Configuration 为配置类 Appconfig.java,然后使用@Bean标签注册组件.
@SpringBootConfiguration注解,效果一致
@Bean("userHaha"):组件在容器中的名字默认是方法名,可以直接修改注解的值"userHaha";配置类本身也是容器中的组件;组件默认是单实例的,可以使用 @Scope("prototype") 进行修改!
快捷键ctrl+F是指:在console中查找指定代码
如何第三方的组件注册到容器?(@Import注解实战以下!!)
–> 在配置类上使用 @Import(FastsqlException.class) 给容器中放指定类型的组件,组件的名字默认是全类名
组件注册:
1、@Configuration 编写一个配置类
2、在配置类中,自定义方法给容器中注册组件。配合@Bean @Scope
3、或使用@Import 导入第三方的组件!
条件注解:如果注解指定的条件成立,则触发指定行为。
@ConditionalOnXxx 放在类级别,如果注解判断生效,整个配置类生效;防在方法级别,单独对该方法进行注解判断。
@ConditionalOnClass:如果类路径中存在这个类,则触发指定行为
@ConditionalOnMissingClass:如果类路径中不存在这个类,则触发指定行为
@ConditionalOnBean:如果容器中存在这个Bean(组件),则触发指定行为
@ConditionalOnMissingBean:如果容器中不存在这个Bean(组件),则触发指定行为
**属性绑定:**将容器中任意组件bean的属性值和配置文件的配置项的值进行绑定。
方法一,使用@ConfigurationProperties(prefix = "pig") 与@Component 标注实体类 Pig
方法二,结合@ConfigurationProperties(prefix = "pig") 在配置类的方法上标注@Bean 实现组件注册
@ConfigurationProperties: 声明组件的属性和配置文件哪些前缀开始项进行绑定
@EnableConfigurationProperties:快速注册注解,用于导入第三方组件进行属性绑定!!!
方法三,在配置类上标注@EnableConfiguraitonProperties(Sheep.class) 实现可快速注册组件。
**场景:**SpringBoot默认只扫描自己主程序所在的包。如果导入第三方包,即使组件上标注了 @Component、@ConfigurationProperties 注解,也没用。因为组件都扫描不进来,此时使用这个注解就可以快速进行属性绑定并把组件注册进容器
2)YAML配置文件:
- 基本语法:
大小写敏感;
使用缩进表示层级关系,k: v,使用空格分割k,v;
缩进时不允许使用Tab键,只允许使用空格换行;
缩进的空格数目不重要,只要相同层级的元素左侧对齐即可;
# 表示注释,从这个字符一直到行尾,都会被解析器忽略。
支持的写法:对象(键值对的组合)、数组、纯量。
多上手提高代码量!并多多注意细节!
Date数据的格式:2010/10/12 12:12:12
注意lombok简化JavaBean开发,自动生成构造器、getter/setter、自动生成builder模式等。

**补充:**使用" - " 是同一层的多个元素,组成一个集合。例如,
dogs:
- name: 小黑
age: 3
- name: 小白
age: 2
3)日志配置
规范:项目开发不要编写
System.out.println(),应该用日志记录信息;

感兴趣日志框架关系与起源可参考:https://www.bilibili.com/video/BV1gW411W76m 视频 21~27集
1. 简介
Spring使用commons-logging作为内部日志,但底层日志实现是开放的。可对接其他日志框架。
spring5及以后 commons-logging被spring直接自己写了。 支持 jul,log4j2,logback。SpringBoot 提供了默认的控制台输出配置,也可以配置输出为文件。 其中,logback是默认使用的。
虽然日志框架很多,但是我们不用担心,使用 SpringBoot 的默认配置就能工作的很好。
SpringBoot怎么把日志默认配置好的?
1、每个starter场景,都会导入一个核心场景spring-boot-starter
2、核心场景引入了日志的所用功能spring-boot-starter-logging
3、默认使用了logback + slf4j组合作为默认底层日志
4、日志是系统一启动就要用,xxxAutoConfiguration是系统启动好了以后放好的组件,后来用的。
5、日志是利用监听器机制配置好的。ApplicationListener。
6、日志所有的配置都可以通过修改配置文件实现。以logging开始的所有配置。
2. 日志格 式
2023-03-31T13:56:17.511+08:00 INFO 4944 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2023-03-31T13:56:17.511+08:00 INFO 4944 --- [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.7]
默认输出格式:(从左往右!)
- 时间和日期:毫秒级精度
- 日志级别:ERROR, WARN, INFO, DEBUG, or TRACE.
- 进程 ID: 例如
4944- —: 消息分割符
- 线程名: 使用[]包含
- Logger 名: 通常是产生日志的类名,例如
o.apache.catalina.core.StandardService- 消息: 日志记录的内容, 例如
Starting service
注意: logback 没有FATAL级别,对应的是ERROR
** **参照:spring-boot包additional-spring-configuration-metadata.json文件
默认输出格式值:%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd'T'HH:mm:ss.SSSXXX}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}
可修改为:'%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{15} ===> %msg%n'

3. 记录日志
Logger logger = LoggerFactory.getLogger(getClass()); //使用@Slf4j注解,则注释该语句
public String hello(){
logger.info("哈哈哈, 方法进来了!");
// 或者使用Lombok的@Slf4j注解! 添加到类上之后,然后使用:
// log.info("哈哈哈,方法进来了");
return "hello";
}
4. 日志级别
– 由低到高:ALL–>TRACE–> DEBUG–> INFO–> WARN–> ERROR–> FATAL–> OFF``;
- 只会打印指定级别及以上级别的日志
- ALL:打印所有日志
- TRACE:追踪框架详细流程日志,一般不使用
DEBUG:开发调试细节日志INFO:关键、感兴趣信息日志WARN:警告但不是错误的信息日志,比如:版本过时ERROR:业务错误日志,比如出现各种异常FATAL:致命错误日志,比如jvm系统崩溃!?OFF:关闭所有日志记录!?
# 默认所有日志没有精确指定级别,就使用root的默认(info)级别;也可修改为其他级别
# logging.level.root=debug
# 精确某个包名的日志级别,就是打印该级别及之后所有类型日志;warn及之后
logging.level.com.atguigu.logging.controller=warn
– 不指定级别的所有类,都使用root指定的级别作为默认级别;
– SpringBoot日志默认级别是 INFO ;
1.可在
application.properties/yaml中配置logging.level.<logger-name>=<level>指定日志级别;
2.level可取值范围:TRACE, DEBUG, INFO, WARN, ERROR, FATAL, or OFF,定义在LogLevel类中;
3.root的logger-name叫root,可以配置logging.level.root=warn,代表所有未指定日志级别都使用 root 的 warn 级别。
5. 日志分组
比较有用的技巧是:
将相关的logger分组在一起,统一配置。SpringBoot 也支持。比如:Tomcat 相关的日志统一设置
# 实现日志分组
logging.group.tomcat=org.apache.catalina,org.apache.coyote,org.apache.tomcat
logging.level.tomcat=trace
SpringBoot 预定义两个组:
| Name | Loggers |
|---|---|
| web | org.springframework.core.codec, org.springframework.http, org.springframework.web, org.springframework.boot.actuate.endpoint.web, org.springframework.boot.web.servlet.ServletContextInitializerBeans |
| sql | org.springframework.jdbc.core, org.hibernate.SQL, org.jooq.tools.LoggerListener |
6. 文件输出
SpringBoot 默认只把日志logging.file.name=demo.log写在控制台,如果想额外记录到文件,可以在application.properties中添加logging.file.name or logging.file.path配置项
# 指定日志文件的路径
logging.file.path=D:\\
# 指定日志文件的名:1、只写名字,生成当前项目位置的demo.log; 2、路径+名字,生成指定路径位置的
logging.file.name=demo.log
logging.file.name=D:\\demo.log
| logging.file.name | logging.file.path | 示例 | 效果 |
|---|---|---|---|
| 未指定 | 未指定 | 仅控制台输出 | |
| 指定 | 未指定 | my.log | 写入指定文件。可以加路径 |
| 未指定 | 指定 | /var/log | 写入指定目录,文件名为spring.log |
| 指定 | 指定 | 同时指定,只以logging.file.name为准 |
7. 文件归档与滚动切割
归档:每天的日志单独存到一个文档中。
切割:每个文件10MB,超过大小切割成另外一个文件。
1.每天的日志应该独立分割出来存档。如果使用logback(SpringBoot 默认整合),可以通过application.properties/yaml文件指定日志滚动规则。
2.如果是其他日志系统,需要自行配置(添加log4j2.xml或log4j2-spring.xml)
3.支持的滚动规则设置如下
# 归档、切割
logging.logback.rollingpolicy.file-name-pattern=${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz
logging.logback.rollingpolicy.max-file-size=1MB
| 配置项 | 描述 |
|---|---|
| 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). |
8. 自定义配置
通常我们配置 application.properties 就够了。当然也可以自定义。比如:
| 日志系统 | 自定义 |
|---|---|
| Logback | logback-spring.xml (推荐), logback-spring.groovy, logback.xml, or logback.groovy |
| Log4j2 | log4j2-spring.xml or log4j2.xml |
| JDK (Java Util Logging) | logging.properties |
如果可能,我们建议您在日志配置中使用-spring 变量(例如,logback-spring.xml 而不是 logback.xml)。如果您使用标准配置文件,spring 无法完全控制日志初始化。
最佳实战:自己要写配置,配置文件名加上 xx-spring.xml,如下图所示:

9. 切换日志组合
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<!-- 排除spring-boot-starter-logging!!! -->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 替换成spring-boot-starter-log4j2 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
log4j2支持yaml和json格式的配置文件
| 格式 | 依赖 | 文件名 |
|---|---|---|
| YAML | com.fasterxml.jackson.core:jackson-databind + com.fasterxml.jackson.dataformat:jackson-dataformat-yaml | log4j2.yaml + log4j2.yml |
| JSON | com.fasterxml.jackson.core:jackson-databind | log4j2.json + log4j2.jsn |
10. 最佳实战
- 导入任何第三方框架,先排除它的默认日志包,因为Boot底层控制好了日志
- 修改
application.properties配置文件,就可以调整日志的所有行为。如果不够,可以编写日志框架自己的配置文件放在类路径下就行,比如logback-spring.xml,log4j2-spring.xml - 如需对接专业日志系统,也只需要把 logback 记录的日志灌倒 kafka之类的中间件,这和SpringBoot没关系,都是日志框架自己的配置,修改配置文件即可
- 业务中使用slf4j-api记录日志。不要再 sout 了

203

被折叠的 条评论
为什么被折叠?



