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文件
?
<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
測試代碼:
@SpringBootConfigurationpublic class AppConfig {@ConditionalOnClass(name="com.alibaba.druid.FastsqlException")@Beanpublic Cat cat01(){return new Cat();//組件名就是方法名}@ConditionalOnMissingClass(value="com.alibaba.druid.FastsqlException")@Beanpublic Dog dog01(){return new Dog();}@ConditionalOnBean(value= Dog.class)@Beanpublic User user1(){User user = new User();user.setUserName("zhangsan");return user;}@ConditionalOnMissingBean(value= Dog.class)@Beanpublic 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作為文件后綴
1. 基本語法
????????? ● 大小寫敏感
????????? ● 使用縮進表示層級關系,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測試代碼:
@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}
????? #對象也可以用{}表示
日志
整合原理
簡介:
1. Spring使用commons-logging作為內部日志,但底層日志實現是開放的。可對接其他日志框架。
? a. spring5及以后 commons-logging被spring直接自己寫了。
2. 支持 jul,log4j2,logback。SpringBoot 提供了默認的控制臺輸出配置,也可以配置輸出為文件。
3. logback是默認使用的。
4. 雖然日志框架很多,但是我們不用擔心,使用 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
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 級別
代碼舉例:
@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=
#日志文件的名與路徑都不配,那么默認配置文件只在控制臺輸出
#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,超過大小切割成另外一個文件。
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.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),排除掉這個框架的默認日志
總結:
1. 導入任何第三方框架,先排除它的日志包,因為Boot底層控制好了日志
2. 修改 application.properties 配置文件,就可以調整日志的所有行為。如果不夠,可以編寫日志框架自己的配置文件放在類路徑下就行,比如logback-spring.xml,log4j2-spring.xml
3. 業務中使用slf4j-api記錄日志。不要再 sout 了