springboot3简介
SpringBoot 帮我们简单、快速地创建一个独立的、生产级别的 Spring 应用(说明:SpringBoot底层是Spring)
大多数 SpringBoot 应用只需要编写少量配置即可快速整合 Spring 平台以及第三方技术
特性:
● 快速创建独立 Spring 应用
○ SSM:导包、写配置、启动运行
● 直接嵌入Tomcat、Jetty or Undertow(无需部署 war 包)【Servlet容器】
○ linux java tomcat mysql: war 放到 tomcat 的 webapps下
○ jar: java环境; java -jar
● 重点:提供可选的starter,简化应用整合
○ 场景启动器(starter):web、json、邮件、oss(对象存储)、异步、定时任务、缓存...
○ 导包一堆,控制好版本。
○ 为每一种场景准备了一个依赖; web-starter(只需要导入这一个,所有有关web的依赖都会导入且会控制好版本)。mybatis-starter
● 重点:按需自动配置 Spring 以及 第三方库
○ 如果这些场景我要使用(生效)。这个场景的所有配置都会自动配置好。
○ 约定大于配置:每个场景都有很多默认配置。
○ 自定义:配置文件中修改几项就可以
● 提供生产级特性:如 监控指标、健康检查、外部化配置等
○ 监控指标、健康检查(k8s)、外部化配置
● 无代码生成、无xml
总结:简化开发,简化配置,简化整合,简化部署,简化监控,简化运维。
快速入门
* 步骤:
* ①创建maven项目,在pom.xml中导入依赖
* 1 所有springboot项目都必须继承自 spring-boot-starter-parent
* <parent>
* <groupId>org.springframework.boot</groupId>
* <artifactId>spring-boot-starter-parent</artifactId>
* <version>3.0.5</version>
* </parent>
* 2 导入web开发的场景启动器
* <dependency>
* <groupId>org.springframework.boot</groupId>
* <artifactId>spring-boot-starter-web</artifactId>
* </dependency>
* ②创建启动SpringBoot项目的主入口程序
* 随便是那个类都可以,在该类上添加@SpringBootApplication注解,代表这是一个SpringBoot应用程序
* 在方法中通过SpringApplication调用静态方法run(当前类.class,args)
* ③正常创建三层架构
代码举例
Pom.xml文件
XML
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- 所有springboot项目都必须继承自 spring-boot-starter-parent -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.5</version>
</parent>
<groupId>com.atguigu</groupId>
<artifactId>boot3-01-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<!-- web开发的场景启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<!-- SpringBoot应用打包插件-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<!--
mvn clean package把项目打成可执行的jar包
java -jar demo.jar启动项目
-->
...
启动类:
@SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class,args);
}
}
注意
springboot的打包插件:
<!-- SpringBoot应用打包插件-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${project.parent.version}</version> <!-- 与父模块一致 -->
</plugin>
</plugins>
</build>
在target目录下可以找到两个jar包,在文件路径下打开它,在改文件路径下打开终端窗口输入java -jar 文件名(回车);即可运行该项目
依赖管理机制
补充:
● 官方提供的场景:命名为:spring-boot-starter-*(官方默认提供了许多场景)
● 第三方提供场景:命名为:*-spring-boot-starter
starter(spring-boot-starter-web--->也叫web场景启动器)的starter(spring-boot-starter)
1、为什么导入starter-web所有相关依赖都导入进来?
(只要导入一个场景启动器,这个场景启动器会自动吧它用到的所有功能的以及相关的依赖导入)
● 开发什么场景,导入什么场景启动器。
● maven依赖传递原则。A-B-C: A就拥有B和C
● 导入 场景启动器。 场景启动器 自动把这个场景的所有核心依赖全部导入进来
2、为什么版本号都不用写?
● 每个boot项目都有一个父项目spring-boot-starter-parent
● parent的父项目是spring-boot-dependencies
● 父项目 (spring-boot-dependencies)版本仲裁中心,把所有常见的jar的依赖版本都声明好了。
● 比如:mysql-connector-j
3、自定义版本号
● 利用maven的就近原则
○ 直接在当前项目properties标签中声明父项目用的版本属性的key
○ 直接在导入依赖的时候声明版本
4 第三方的jar包
● boot父项目没有管理的需要自行声明好版本号

自动配置机制
初步理解
● 自动配置的 Tomcat、SpringMVC 等
○ 导入场景,容器中就会自动配置好这些场景的核心组件。
代码测试:
@SpringBootApplication
public class Boot302DemoApplication {
public static void main(String[] args) {
//java10:局部变量类型的自动推断
var ioc = SpringApplication.run(Boot302DemoApplication.class, args);
//1 获取ioc容器中所有组件的名字------->SpringBoot把以前配置的核心组件都给我们配置好了。
String[] names = ioc.getBeanDefinitionNames();
for (String name:names) {
System.out.println("name = " + name);
}
}
}

● 默认的包扫描规则
○ @SpringBootApplication 标注的类就是主程序类
○ SpringBoot只会扫描主程序所在的包及其下面的子包,自动的component-scan功能
○ 自定义扫描路径
方式1 @SpringBootApplication(scanBasePackages = "com.atguigu")-----------用属性
方式2 @ComponentScan("com.atguigu") 直接指定扫描的路径
本质: @SpringBootApplication=@ComponentScan+@SpringBootConfiguration+@EnableAutoConfiguration
● 配置默认值
○ 配置文件的所有配置项是和某个类的对象值进行一一绑定的。
○ 绑定了配置文件中每一项值的类: 属性类。
○ 比如:
■ ServerProperties绑定了所有Tomcat服务器有关的配置
■ MultipartProperties绑定了所有文件上传相关的配置
● 按需加载自动配置
○ 导入场景spring-boot-starter-web
○ 场景启动器除了会导入相关功能依赖,导入一个spring-boot-starter,是所有starter的starter,基础核心starter
○ spring-boot-starter导入了一个包 spring-boot-autoconfigure。包里面都是各种场景的AutoConfiguration自动配置类
○ 虽然全场景的自动配置都在 spring-boot-autoconfigure这个包,但是不是全都开启的。
■ 导入哪个场景就开启哪个自动配置
总结: 导入场景启动器、触发 spring-boot-autoconfigure这个包的自动配置生效、容器中就会具有相关场景的功能
常用注解
组件注解
@Configuration 、//说明这是一个配置类
@SpringBootConfiguration 、 //代表此类是一个Springboot的配置类
@Bean、//替代bean标签
@Scope、//组件默认是单实例的,可以通过此注解设置单个还是多个
@Controller、 @Service、@Repository、@Component
@Import、//导入第三方组件到ioc容器(给容器中方指定类型的组件,组件的名字默认是全类名)
@ComponentScan
组件注册步骤:
1、@Configuration 编写一个配置类
2、在配置类中,自定义方法给容器中注册组件。配合@Bean
3、或使用@Import 导入第三方的组件
条件注解
如果注解指定的条件成立,则触发指定行为
@ConditionalOnXxx
@ConditionalOnClass(name="类的权限定符"):如果类路径中存在这个类,则触发指定行为
@ConditionalOnMissingClass:如果类路径中不存在这个类,则触发指定行为
@ConditionalOnBean:如果容器中存在这个Bean(组件),则触发指定行为
@ConditionalOnBean(value=组件类型,name=组件名字):判断容器中是否有这个类型的组件,并且名字是指定的值
@ConditionalOnMissingBean:如果容器中不存在这个Bean(组件),则触发指定行为
注意:这些注解还可以用在类上;
放在类级别:如果注解判断生效整个配置配才生效;
放在方法级别:只是单独对这个方法判断;
场景:
● 如果存在FastsqlException这个类,给容器中放一个Cat组件,名cat01,
● 否则,就给容器中放一个Dog组件,名dog01
● 如果系统中有dog01这个组件,就给容器中放一个 User组件,名zhangsan
● 否则,就放一个User,名叫lisi
测试代码:
java
@SpringBootConfiguration
public class AppConfig {
@ConditionalOnClass(name="com.alibaba.druid.FastsqlException")
@Bean
public Cat cat01(){
return new Cat();//组件名就是方法名
}
@ConditionalOnMissingClass(value="com.alibaba.druid.FastsqlException")
@Bean
public Dog dog01(){
return new Dog();
}
@ConditionalOnBean(value= Dog.class)
@Bean
public User user1(){
User user = new User();
user.setUserName("zhangsan");
return user;
}
@ConditionalOnMissingBean(value= Dog.class)
@Bean
public User user2(){
User user = new User();
user.setUserName("lisi");
return user;
}
}
属性绑定
@ConfigurationProperties: 声明组件的属性和配置文件哪些前缀开始项进行绑定(名字要一致)(既能表在类上也能标在方法上,用了此注解,组件一定要加入到ioc容器)
@EnableConfigurationProperties:快速注册注解
常用于导入第三方组件进行属性绑定,springboot默认只扫描自己主程序所在的包,所以别人写好的类使用@Component与@ConfigurationProperties(prefix = "...")配置好了组件,我们也无法扫描到,所以只能使用@EnableConfigurationProperties配置属性值并将起放入到ioc容器中
将容器中任意组件(Bean)的属性值和配置文件的配置项的值进行绑定
步骤:
● 1、给容器中注册组件(@Component、@Bean)----------------组件只有在容器中才有这些功能
● 2、使用@ConfigurationProperties 声明组件和配置文件的哪些配置项进行绑定
@ConfigurationProperties+@Component代码举例:
文件:
pig.id=1
pig.name=佩奇
pig.age=5
要放入ioc的组件的类
@Component
@ConfigurationProperties(prefix = "pig")
/*
注意:配置文件的的名字只要与类中的属性名一一对应就可以赋值
*/
@Data
public class Pig {
private Long id;
private String name;
private Integer age;
}
@EnableConfigurationProperties代码举例
配置文件:
sheep.id=2
sheep.name=苏西
sheep.age=4
实体类@Data
@ConfigurationProperties(prefix = "sheep")//没有搭配@Component了因为在配置类上开启了开启组件的属性绑定
public class Sheep {
private Long id;
private String name;
private Integer age;
}
在配置类上加:
@EnableConfigurationProperties(Sheep.class)
/**
* 1 开启组件的属性绑定
* 2 默认会将组件放入到ioc容器中
* 注意:还是要使用@ConfigurationProperties(prefix = "sheep")指明前缀
*/
深入了解自动配置原理
springboot 完整流程
①springboot怎么实现导入一个starter,写一些简单配置,应用就能跑起来,我们无需关心整合
②为什么tomcat的端口号可以配置在appliction.properties中,并且Tomcat能启动成功
③导入场景后那些自动配置能生效
1、导入starter-web:导入了web开发场景
● 1、场景启动器导入了相关场景的所有依赖:starter-json、starter-tomcat、springmvc
● 2、每个场景启动器都引入了一个spring-boot-starter,核心场景启动器。
● 3、核心场景启动器引入了spring-boot-autoconfigure包。
● 4、spring-boot-autoconfigure里面囊括了所有场景的所有配置。(所以导入的所有依赖都不需要写版本)--所有场景要用的组件在配置类里都写好了,这些配置类就在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 开启自动配置的核心。
○ 1. 是由@Import(AutoConfigurationImportSelector.class)提供功能:批量给容器中导入组件。
○ 2. SpringBoot启动会默认加载 142个配置类。
○ 3. 这142个配置类来自于spring-boot-autoconfigure下 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件指定的
○ 项目启动的时候利用 @Import 批量导入组件机制把 autoconfigure 包下的142 xxxxAutoConfiguration类导入进来(自动配置类)
○ 虽然导入了142个自动配置类
● 4、按需生效:
○ 并不是这142个自动配置类都能生效
○ 每一个自动配置类,都有条件注解@ConditionalOnxxx,只有条件成立,才能生效
3、xxxxAutoConfiguration自动配置类
● 1、给容器中使用@Bean 放一堆组件。
● 2、每个自动配置类都可能有这个注解@EnableConfigurationProperties(ServerProperties.class),用来把配置文件中配的指定前缀的属性值封装到 xxxProperties属性类中
● 3、以Tomcat为例:把服务器的所有配置都是以server开头的。配置都封装到了属性类中。
● 4、给容器中放的所有组件的一些核心参数,都来自于xxxProperties。xxxProperties都是和配置文件绑定。
● 5、只需要改配置文件的值,核心组件的底层参数都能修改
4、写业务,全程无需关心各种整合(底层这些整合写好了,而且也生效了)
1、导入starter,就会导入autoconfigure包。
2、autoconfigure 包里面 有一个文件 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports,里面指定的所有启动要加载的自动配置类
3、@EnableAutoConfiguration 会自动的把上面文件里面写的所有自动配置类都导入进来(通过@Import批量导入)xxxAutoConfiguration(配置类) 是有条件注解进行按需加载
4、xxxAutoConfiguration给容器中导入一堆组件,组件都是从 xxxProperties(属性类,它绑定了配置文件,所以只要修改配置文件就可以修改组件参数)中提取属性值
5、xxxProperties又是和配置文件进行了绑定
效果:导入starter、修改配置文件,就能修改底层行为。
yaml文件语法
痛点:SpringBoot 集中化管理配置,application.properties
问题:配置多以后难阅读和修改,层级结构辨识度不高
YAML 是 "YAML Ain't a Markup Language"(YAML 不是一种标记语言)。在开发的这种语言时,YAML 的意思其实是:"Yet Another Markup Language"(是另一种标记语言)。
● 设计目标,就是方便人类读写
● 层次分明,更适合做配置文件
● 使用.yaml或 .yml作为文件后缀
- 基本语法
● 大小写敏感
● 使用缩进表示层级关系,k: v,使用冒号+空格分割k,v
● 缩进时不允许使用Tab键,只允许使用空格。换行
● 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
● # 表示注释,从这个字符一直到行尾,都会被解析器忽略。
细节
● birthDay 推荐写为 birth-day
● 文本:(\n在单引号内不生效,在双引号内生效)
○ 单引号不会转义【\n 则为普通字符串显示】
○ 双引号会转义【\n会显示为换行符】
例如:name:'zhangsan \n 123'---->打印:name=zhangsan \n 123
name:"张三 \n 457"----》打印:name=张三(换行) 123
● 大文本
○ |开头,大文本写在下层,保留文本格式,换行符正确显示
○ >开头,大文本写在下层,折叠换行符(若没有缩进会压缩换行,即将换行变为空格;若有缩进则保留原文本格式)
例如:
text:
abc
gii
|
dogs:
- dogName: xiaohei
dogAge: 1
- dogName: xiaohuang
dogAge: 1
- >
cghdsku
gsdvkj
ghusduvch
打印:

● 多文档合并
○ 使用---可以把多个yaml文档合并在一个文档中,每个文档区依然认为内容独立
支持的写法:
● 对象:键值对的集合,如:映射(map)/ 哈希(hash) / 字典(dictionary)
● 数组:一组按次序排列的值,如:序列(sequence) / 列表(list)
● 纯量:单个的、不可再分的值,如:字符串、数字、bool、日期
.properties测试代码:
java
@Component
@ConfigurationProperties(prefix = "person")//和配置文件person前缀的所有配置进行绑定
@Data
@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
}
child类
@Data
public class Child {
private String name;
private Integer age;
private Date birthDay;
private List<String> text;
}
dog类
@Data
public class Dog {
private String dogName;
private int dogAge;
}
cat类
@Data
public class Cat {
private String catName;
private int catAge;
}
Applicationl.properties文件
#properties表示复杂对象
person.name=张三
person.age=30
person.birthDay=1996/10/12 12:12:12
person.like=true
person.child.name=李四
person.child.age=12
person.child.brithDay=2013/12/12
person.child.text[0]=abc
person.child.text[1]=gcs
person.dogs[0].dogName=小黄
person.dogs[0].dogAge=1
person.dogs[1].dogName=小黑
person.dogs[1].dogAge=1
person.cats.c1.catName=小暖
person.cats.c1.catAge=1
person.cats.c2.catName=小白
person.cats.c2.catAge=1
#子对象用嵌套;数组用[];Map用.
.yaml测试代码:
person:
name: zhangsan
age: 30
birthDay: 1996/12/10
like: true
child:
name: lisi
age: 12
birthDay: 2013/2/23
text: ["abc","gdk"]
text:
abc
gii
dogs:
- dogName: xiaohei
dogAge: 1
- dogName: xiaohuang
dogAge: 1
cats:
c1:
catName: xiaonuan
catAge: 1
c2: {catName: xiaobai,catAge: 2}
#对象也可以用{}表示
日志
整合原理
简介:
- Spring使用commons-logging作为内部日志,但底层日志实现是开放的。可对接其他日志框架。
a. 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开始的所有配置。
日志格式与记录日志
默认输出格式:
● 时间和日期:毫秒级精度
● 日志级别:ERROR, WARN, INFO, DEBUG, or TRACE.
● 进程 ID
● ---: 消息分割符
● 线程名: 使用[]包含
● Logger 名: 通常是产生日志的类名
● 消息: 日志记录的内容
注意: logback 没有FATAL级别,对应的是ERROR

记录日志:
Logger logger = LoggerFactory.getLogger(getClass());------------》logger.info("要记录的内容")
或者使用Lombok的@Slf4j注解----------------》log.info("要记录的内容")
例如:
@Slf4j
@RestController
public class HelloController {
Logger logger = LoggerFactory.getLogger(getClass());
@GetMapping("/h")
public String hello(){
/**
* 实现:方法一进来就打印日志
* 方法一:通过LoggerFactory调用getLogger(getClass())传入当前类-----得到一个 Logger对象logger,
* 通过对象logger调用info就可以记录想要的东西了
* 方法二:注解@Slf4j中有一个log
* 通过log调用info也可以传入属性
*/
logger.info("哈哈哈,方法进来了1");
log.info("哈哈哈,方法进来了2");
return "hello";
}
}
日志级别
● 由低到高:ALL,TRACE, DEBUG, INFO, WARN, ERROR,FATAL,OFF;
○ 只会打印指定级别及以上级别的日志
○ ALL:打印所有日志
○ TRACE:追踪框架详细流程日志,一般不使用
○ DEBUG:开发调试细节日志
○ INFO:关键、感兴趣信息日志
○ WARN:警告但不是错误的信息日志,比如:版本过时
○ ERROR:业务错误日志,比如出现各种异常
○ FATAL:致命错误日志,比如jvm系统崩溃(logback 没有FATAL级别,对应的是ERROR)
○ OFF:关闭所有日志记录
● 不指定级别的所有类,都使用root指定的级别作为默认级别
● SpringBoot日志默认级别是 INFO
-
在application.properties/yaml中配置logging.level.<logger-name>=<level>指定日志级别(我们可以精确的调节某一个类的日志级别后某一个包下的日志级别)
-
level可取值范围:TRACE, DEBUG, INFO, WARN, ERROR, FATAL, or OFF,定义在 LogLevel类中
-
root 的logger-name叫root,可以配置logging.level.root=warn,代表所有未指定日志级别都使用 root 的 warn 级别
代码举例:
@Slf4j
@RestController
public class HelloController {
Logger logger = LoggerFactory.getLogger(getClass());
@GetMapping("/h")
public String hello(String a,String b){
log.trace("trac 日志....");
log.debug("debug 日志....");
log.info("info 日志....");
log.warn("warn 日志....,参数a:{} b:{}",a,b);
log.error("error 日志....");
/**
* 只打印了info,warn,error日志
*springboot底层默认的日志级别是info(只会打印info及以后级别的日志)
*/
return "hello";
}
}
Applicaton.properties文件
#默认所有日志没有精确指定级别就使用root的默认级别(info)
#将默认级别调整为debug级别
logging.level.root=debug
#将controller包下的日志级别调整为warn级别
logging.level.com.atgiugu.logging1.controller=warn
日志分组
将相关的logger分组在一起,统一配置。SpringBoot 也支持。比如:Tomcat 相关的日志统一设置
例如:
#日志分组
#调整某个包下的日志级别
#logging.level.com.atgiugu.logging1.controller=debug
#logging.level.com.atgiugu.logging1.service=debug
#logging.level.com.aaa=debug
#logging.level.com.bbb=debug
logging.group.abc=com.atgiugu.logging1.controller,com.atgiugu.logging1.service,com.aaa,com.bbb
logging.level.abc=debug
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 |
文件输出(将日志信息保存到文件中)
SpringBoot 默认只把日志写在控制台,如果想额外记录到文件,可以在application.properties中添加logging.file.name or logging.file.path配置项。
例如:
Application.properties文件
#指定日志文件的路径(只给了一个地址的话,会在指定路径下生成一个默认名字的文件)
#logging.file.path=
#指定日志文件的名
#logging.file.name=
#日志文件的名与路径都不配,那么默认配置文件只在控制台输出
#1 只写名字,就生成到当前项目同位置的demo.log
#logging.file.name=demo.log
#2 名字+路径,就生成到指定位置的指定文件
logging.file.name=C://demo.log
#注意:如果logging.file.path=与logging.file.name=同时存在,那么以logging.file.name优先
|-------------------|-------------------|----------|-----------------------|
| logging.file.name | logging.file.path | 示例 | 效果 |
| 未指定 | 未指定 | | 仅控制台输出 |
| 指定 | 未指定 | my.log | 写入指定文件。可以加路径 |
| 未指定 | 指定 | /var/log | 写入指定目录,文件名为spring.log |
| 指定 | 指定 | | 以logging.file.name为准 |
文件归档与滚动切割
归档:每天的日志单独存到一个文档中。
切割:每个文件10MB,超过大小切割成另外一个文件。
-
每天的日志应该独立分割出来存档。如果使用logback(SpringBoot 默认整合),可以通过application.properties/yaml文件指定日志滚动规则。
-
如果是其他日志系统,需要自行配置(文件名一定为log4j2.xml或log4j2-spring.xml)
-
支持的滚动规则设置如下
|------------------------------------------------------|-----------------------------------------------------------|
| 配置项 | 描述 |
| 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). |
例如:
Application.properties文件:
#归档与切割
logging.logback.rollingpolicy.file-name-pattern=${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz
#${LOG_FILE}就是前面配置的文件名;%d{yyyy-MM-dd}格式化一个日期,是年月日;%i是当天的第几个文件;gz是压缩包格式
#只要文件攒够1MB就切割为一个单独文件
logging.logback.rollingpolicy.max-file-size=1MB
自定义日志系统
通常我们配置 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 无法完全控制日志初始化。
切换日志组合
利用maven的就近原则
步骤:①在spring-boot-starter中排除logback依赖(spring-boot-starter-logging)
②导入log4j2的依赖(spring-boot-starter-log4j2)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
导第三方日志如果它依赖了一个日志(jul),排除掉这个框架的默认日志
总结:
-
导入任何第三方框架,先排除它的日志包,因为Boot底层控制好了日志
-
修改 application.properties 配置文件,就可以调整日志的所有行为。如果不够,可以编写日志框架自己的配置文件放在类路径下就行,比如logback-spring.xml,log4j2-spring.xml
-
业务中使用slf4j-api记录日志。不要再 sout 了