目录
一、什么是SpringBoot
1.1、什么是springboot
SpringBoot基于Spring开发,不仅继承了Spring框架原有的优秀特性,他并不是用来替代Spring的解决方案,而和Spring框架紧密结合进行一步简化了Spring应用的整个搭建和开发过程。其设计目的是用来简化Spring应用的初始搭建以及开发过程,怎么简化的呢?就是通过提供默认配置等方式让我们更容易使用。
关于SpringBoot还有一句出名的话就是约定大于配置,采用Spring Boot可以大大简化开发模式,它集成了大量常用的第三方库配置,所有想要集成的常用框架,都有对应的组件支持,例如Redis、MongoDB、Dubbo、Kafka、ES等等。Spring Boot应用这些第三方库几乎可以零配置地开箱即用,大部分的SpringBoot应用都只需要非常少量的配置代码,开发者能够更加专注于业务逻辑。另外SpringBoot通过集成大量的框架使得依赖包的版本冲突,以及引用的不稳定等问题得到了很好的解决。
约定大于配置
在Spring中,会涉及很多静态资源如css、图片等都要去给Spring MVC设置静态资源的文件映射,很麻烦
Spring Boot 则约定静态资源文件存放在特定文件夹下,就不需要再去配置了,它会自动去扫描。
众多框架中所需要的大量且繁琐的配置文件,所以SpringBoot是一个服务于框架的框架,服务的范围就是简化配置文件。
1.2、可以做什么
最显著的特点就是让文件配置变得简单,让应用配置也变得简单,可以快速开启一个web容器来进行开发
1.3、工程使用特点
(1)springboot本身时不需要在pom.xml文件添加什么配置的,如果与其他软件合用,比如POSTMAN和Swagger则需要在pom.xml文件中添加依赖
(2)我们之前在ssm和ssh开发中,在resources中储存各种对应框架的配置文件,而现在我们只需要一个yml配置文件就行了,配置文件有服务器端口号,数据库连接的地址,用户名,密码。这样虽然简单,但是也不安全。
(3)在Springboot创建时会自动创建启动类,也就是启动开关,并且不需要tomcat,自带服务器,但要注意端口冲突
1.4、优点
-
快速构建一个独立的Spring程序
-
嵌入Tomcat,jetty或者Undertow,无需部署WAR文件
-
提供starter POMs来简化Maven配置和减少版本冲突带来的问题
-
对Spring和第三方库提供默认配置,也可以修改默认值,简化框架配置
-
提供生产就绪型功能,如指标、健康检测和外部配置
-
无需配置XML,无代码生成,开箱即用
1.5、为什么要使用SpringBoot
SpringBoot简化了基本的Spring开发只是最直观的一方面,另一方面,也更得力于各微服务组件的支持,这也是谈SpringBoot比谈微服务的原因。(起初是Netfilx移植到Spring),可以说SpringCloud带动了SpringBoot,SpringBoot成就了SpringCloud。
SpringBoot和SpringCloud的区别
-
SpringBoot是一个快速开发的框架,能够快速的整合第三方框架,简化XML配置,全部采用注解形式,内置Tomcat容器,帮助开发者能够实现快速开发,SpringBoot的Web组件默认集成的是SpringMVC框架。
-
SpringMVC是控制层。
-
SpringCloud依赖于SpringBoot组件,使用SpringMVC编写Http协议接口,同时SpringCloud是一套完整的微服务解决框架。
SpringBoot和SpringMVC的区别
因为SpringBoot是一个快速的开发的框架,能够帮助开发人员快速的能够整合第三方框架、内嵌入第三方常用容器(tomcat、 jetty、 undertow)、 完全简化xml配置,采用注解形式: spring-boot- -starter-web
整 合Spr ingMVC
、Spring
SpringBootweb
组件采用SpringMVC
框架。
二、SpringBoot快速搭建
2.1、环境准备
-
本次使用的是SpringBoot 2.6.6版本
-
Maven 3.5+
-
Java 8
开发工具
Idea 2018+(需要配置Maven、jdk)
2.2、创建SpringBoot工程
1、新建工程
点击Spring Intitializr创建SpringBoot
点击next,选择SpringBoot版本以及需要的服务然后点击Finish
创建完成
2、编写启动类
在启动类同级创建一个controller包,创建HelloController类
@RestController //@Controller + @ResponseBody
@RequestMapping("/hello")
public class HelloController {
@RequestMapping("/world")
public String hello(){
return "hello world!";
}
}
3、启动项目
点击运行即可 ,不需要去配置Tomcat
在网页输入自己定义的URL路径,即可看到返回的字符串
此时一个简单的SpringBoot项目就弄好了,方便又快捷!
4、通过到jar包运行
前提是maven中需要有一个启动插件,但是如果使用自动装配的话,Idea'就会自动装配该plugins
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
点击maven,然后package打包即可
在左侧target就可以看到已打包的jar包了
在该文件夹内进入cmd模式,cmd模式就是在地址栏内输入cmd即可
在cmd输入java -jar jar包名 即可
如果出现No active profile set, falling back to default profiles: default这个报错
那么就是没有添加spring-boot-starter-web依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
这样将web应用部署在服务器内就不需要在服务器内搭建复杂的环境,只需要打成jar包运行即可。
2.3、端口配置
如果端口存在冲突问题,配置端口即可
1、在resources下的application.properties添加配置
启动项目,此时项目路径有了变化,因为加了一个虚拟路径
这样就解决了端口冲突问题了!
三、Spring Boot配置文件和自动配置原理
3.1、继承关系的项目
在平时写项目的时候,不可能把整个项目都写在一个文件下,这样就体现不出微服务的特点了,既然如此,就可以通过创建一个父项目和若干子项目,共同合成一个完整的项目,子项目是继承父项目的。
操作:
1、使用Spring Initializr新建一个父maven
创建完成后,删除其余文件
3.2、添加子模块
通过父项目创建子项目
项目建完后如下
查看两个项目的pom,可以发现,其实还不算是真正意义上的继承
所以,我们需要将子项目parent放成父项目的
这才是正确的继承关系!
3.3、配置文件的使用
SpringBoot使用一个全局的配置文件 核心配置文件,配置文件名在约定的情况下名字是固定的(约定大于配置)
配置文件的作用:修改SpringBoot自动配置的默认值,SpringBoot在底层都给我们自动配置好。
-
application.properties
-
application.yml
两种配置文件的格式
在SpringBoot框架中,resources文件夹里可以存放配置的文件有两种:properties和yml
.properties格式(扁平的k/v格式):
server.port=8088
.yml格式(树型结构):
server: port: 8080
建议使用yml,可读性强!yml对格式非常敏感
3.4、配置文件加载顺序
在父项目中pom里ctrl + 鼠标左键点击spring-boot-starter-parent查看源码即可
如果同时存在不同后缀的文件就按照这个顺序加载主配置文件,且为互补配置。
3.4.1、外部约定配置文件加载顺序
SpringBoot启动还会扫描以下位置的application.properties或者application.yml文件作为SpringBoot的默认配置文件
由低到高为:
1.classpath根目录下的
2.classpath根/config
3.项目根目录
如果当前项目是继承/耦合关系的maven项目的话,项目根目录=父maven项目根目录
4.项目根目录/config
5.直接子目录/config
这个是直接通过命令行来执行,先打包成jar包,通过cmd来执行
注意:
这里可能会打包不成功,只需要在父项目的pom里添加<packaging>pom</packaging>即可
是在当前项目打包而不是父项目哦!
在cmd运行一下,发现它的端口是8081,所以第三第四一般都不会使用!
运行时要注意端口冲突问题。
java -jar spring_one-0.0.1-SNAPSHOT.jar --server.port=8085
除此之外,还可以指定配置文件的地址!!
java -jar spring_one-0.0.1-SNAPSHOT.jar --server.port=E:\config/
这里不做详细介绍。
3.5、Profile文件的加载
Profile意思是配置,对于应用程序来说,不同的环境需要不同的配置
SpringBoot框架提供了多profile的管理功能,我们可以使用profile功能来区分不同环境的配置
3.5.1、多Profile文件
spring官方给出的语法为:application-{profile}.properties(.yml/.yaml)
3.5.2、自定义Profile文件
如果需要创建自定义的匹配文件时,可以使用application-自定义名字.properties(.yml/.yaml)的命名方式,根据实际情况来创建。
本次演示则在resources下创建了config包,里面创建了一个配置文件,通过(spring.profiles.active 版本 )来控制版本信息,因为它的优先级比根目录要高。
在根目录创建三个版本,分别是application.yml(初始版本)、application-dev.yml(测试版本)、application-prod.yml(发行版本)
application.yml(初始版本):
server:
port: 8080
servlet:
context-path: /yml
application-dev.yml(测试版本):
server:
port: 8082
servlet:
context-path: /config_dev
application-prod.yml(发行版本)
server:
port: 8083
servlet:
context-path: /config_prod
项目结构:
config下的配置文件application.yml:
server:
port: 8081
servlet:
context-path: /xiaotian
spring:
profiles:
active: dev
运行项目,查看项目端口号:
可以看到,端口号就是8082,且虚拟路径改为了该版本的虚拟路径了。
3.5.3、对Bean的profile的管理
springboot提供了@Profile()注解,意思是:如果当前环境为dev,注解内也为dev那么该注解生效,则这个内可以运行,反之则不行。
这里创建两个controller类,通过添加不同的@Profile()来实现profile对类的控制。
HelloController类:
@Profile("yml")
@RestController
@RequestMapping("/hello")
public class HelloController {
@RequestMapping("/sayHi")
public String hello(){
return "hello spring boot yml";
}
}
HelloController_dev类:
@Profile("dev")
@RestController
@RequestMapping("/hello")
public class HelloController_dev {
@RequestMapping("/sayHi")
public String hello(){
return "hello spring boot dev";
}
}
版本控制为dev:
spring:
profiles:
active: dev
运行结果:
可以看出当前环境为dev环境
不仅如此,还可以通过打包,在cmd窗口直接选择指定文件的配置文件为当前环境,或者指定配置文件都可以,这里不做详细介绍。
四、配置文件值注入
将YML映射到属性
-
字面量:普通的值(数字,字符串,布尔)
-
对象、Map(属性和值)(键值对)
4.1、创建实体类
这里使用了lombok来构造,只需要在父项目添加lombok依赖即可
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency>
User类:
@Component
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User<Address> {
private String username;
private Integer age;
private Date birthday;
private List<String> hobbies;
private Map<String,Integer> family;
private Address address;
}
Address类:
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Address {
private Integer id;
private String desc;
}
测试环境是否搭建完成,用test测试打印user
@Autowired
private User user;
@Test
void contextLoads() {
System.out.println(user);
}
4.2、yml注入数据
1、在配置文件中写入要注入的值
user:
username: 小天
2、在实体类中的属性上通过@Value注解注入值
通过@Value + SPEL表达式(${xxxxx})直接绑定springboot配置文件中的值
@Value("${user.username}")
private String username;
3、测试
添加成功!
可是如果这样的话效率会很低,总不能一个一个在属性上通过@Value注入值吧,这里就可以用到@ConfigurationProperties(prefix = "前缀"),只需要加上前缀,就会自动注入
prefix 属性可以指定配置文件中的某一个节点,该节点中的子节点将自动和属性进行绑定
@ConfigurationProperties和@Value获取值比较
@ConfigurationProperties | @Value | |
---|---|---|
功能 | 批量注入配置文件中的属性 | 一个一个指定 |
松散绑定 | 支持 | 有限制 |
SpEL | 不支持 | 支持 |
JSR303数据校验 | 支持 | 不支持 |
4.2.1、松散绑定
user:
USERNAME: 小天
user:
userName: 小天
user:
user_name: 小天
user:
user-name: 小天
以上4中命名是可以自动绑定bean属性
4.2.2、配置文件自动提示
在yml中写参数时没有提示是很麻烦的,那么就需要导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
这样再yml配置文件写入数据的时候就会有提示了!
4.2.3、复杂类型封装
user:
username: 小天
age: 20
birthday: 2022/4/16
hobbies: [打代码,还是打代码,终于可以看电视了]
family: {father: 45,mother: 45}
address:
id: 1
desc: earth
4.2.4、引用占位符
4.2.5、设置随机值
my:
secret: "${random.value}"
number: "${random.int}"
bignumber: "${random.long}"
uuid: "${random.uuid}"
number-less-than-ten: "${random.int(10)}"
number-in-range: "${random.int[1024,65536]}"
4.2.6、JSR303数据校验
操作前需要先导入依赖
<!--数据校验-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
在类中的属性上加上注解
该注解为import javax.validation.constraints.NotNull;包下的!!!
@NotNull
private Address address;
将yml中对应值去掉在运行项目即可
# address:
# id: 1
# desc: ${user.username}家在earth
@NotNull:不能为null,但可以为empty @NotEmpty:不能为null,而且长度必须大于0 @NotBlank:只能作用在String上,不能为null,而且调用trim()后,长度必须大于0。(trim()删除字符串的头尾空白符)
4.2.7、指定配置文件
如果想将特定的user数据放在一个配置文件内,那么可以使用@PropertySource注解
@PropertySource("classpath:data/user.properties")
@PropertySource内的参数是配置文件路径,且必须是.properties文件!
这里有点小问题,设置了但是读取到的依然是根目录下的yml文件的数据
五、自动配置类读取原理
5.1、@SpringBootApplication
@SpringBootApplication:spring boot 应用标注在某个类上说明这个类是SpringBoot的主配置类,它需要运行这个类的main方法来启动springboot应用。
Ctrl+点击@SpringBootApplication查看源码:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
...
元注解:
-
@Target({ElementType.TYPE})
-
设置当前注解可以标记在哪,这里是TYPE,就是可以标记在类上面
-
-
@Retention(RetentionPolicy.RUNTIME)
-
RUNTIME会被JVM加载
-
-
@Documented
-
java doc会生成注解信息
-
-
@Inherited
-
标记是否会被继承
-
重要的几个注解:
-
@SpringBootConfiguration:Spring Boot配置类
-
标注在某个类上,表示这是一个SpringBoot的配置类
-
-
@EnableAutoConfiguration:开启自动配置功能
-
以前需要配置的东西,springboot帮我们配置;@EnableAutoConfiguration告诉springboot开启自动配置功能,这样自动配置才能生效
-
-
@ComponentScan:扫描包,相当于在spring.xml配置context:comonent-scan
-
如果没有指定basepackage,如果没有指定,spring底层会自动扫描当前配置类所所存在的包
-
TypeExcludeFilter
-
springboot对外提供的扩展类,可以让我们按照自己的方式进行过滤排除
-
-
AutoConfigurationExcludeFilter
-
排除所有配置类,并且是自动配置类的其中一个
-
-
5.2、EnableAutoConfiguration
Ctrl+点击@EnableAutoConfiguration查看源码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
...
前面四个元注解就不做讲解
1、@AutoConfigurationPackage
将当前配置类所在包保存在BasePackages的Bean中。供Spring内部使用
2、AutoConfigurationImportSelector
AutoConfigurationImportSelector继承自DeferredImportSelector接口,而DeferredImportSelector接口又继承自ImportSelector接口,在ConfigurationClassParser的processImports方法中有对DeferredImportSelector作特别处理,把这样的类放到了最后再做处理。最开始的触发点在ConfigurationClassPostProcessor,这个后置处理器使用了ConfigurationClassParser的parse方法,我们可以看到这个parse方法里面再调用parse完所有的BeanDefinitionHolder之后,再调用this.deferredImportSelectorHandler.process()处理的,所以这也就是为什么我们写的配置要优先于springboot的自动配置的原因。
小结:
@springbootApplication的注解引入@EnableAutoConfiguration注解,里面引入的importSelect就是延迟selector,spring先处理我们的,然后再处理自动装配的,那些自动配置类上的那些条件就可以根据我们的配置情况来判断是否应该生效
六、热部署
6.1、什么是热部署
热部署是指在你修改项目BUG的时候对JSP或JAVA类进行了修改在不重启WEB服务器前提下能让修改生效。但是对配置文件的修改除外!
6.2、开启热部署
1、导入热部署依赖
<!--devtools热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
2、在IDEA中配置
添加完依赖后,idea不会自动编译,还需要修改idea配置
-
File==> Settings ==> Build, Execution, Deployment==>Compiler==>Build project automatically
-
ctrl+shift+alt+/ 选择Registry,勾选Compiler autoMake allow app running
如果发现没有Compiler autoMake allow app running这个选项那么执行一下操作
这样热部署就可以用了,运行项目,然后修改内容试试看吧。
热部署推荐一个好用的插件JRebel哦
七、日志
在工作中,可能会遇到领导突然让你将项目的日志更改为其他比如log4j更改为jul这样就会很麻烦,但是通过日志门面我们就可以在各种日志之间转换。
解决jar包中应用的日志框架各不相同,使用适配器和桥接器可以很好的解决
7.1、SLF4J
SLF4J是为各种 loging APIs提供一个简单统一的接口,从而使得最终用户能够在部署的时候配置自己希望的loging APIs实现。Logging API实现既可以选择直接实现SLF4J接口的loging APIs如: logback、SimpleLogger。也可以通过开发相应的适配器来使用已有的API实现如 Log4jLoggerAdapter、JDK14LoggerAdapter 等。SLF4J的基础图如下所示:
7.1.1、slf4j与其他各种日志组件的桥接
7.2、只实现日志方式
7.2.1、创建log4j项目类
1、先添加log4j的依赖
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
2、初始化Log4j属性,在resources下添加log4j.properties配置文件
#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
log4j.rootLogger=DEBUG,console,file
#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n
#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/logFile.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n
#日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
3、实现log4j日志
//Log4j日志
public class Log4jMain {
public static void main(String[] args){
Logger logger = LoggerFactory.getLogger(Log4jMain.class);
System.out.println(logger.getClass());
logger.info("这是Log4j日志文件的输出");
}
}
注意这里的Logger的包导入的是:import org.apache.log4j.Logger;
4、日志输出:
7.2.2、创建Jul项目类
1、直接创建
//Jul日志
public class JulMain {
public static void main(String[] arge){
Logger logger = Logger.getLogger(JulMain.class.getName());
System.out.println(logger.getClass());
logger.info("这是Jul日志文件的输出");
}
}
注意这里的Logger的包导入的是:import org.apache.commons.logging.Log;
2、运行项目查看日志文件:
小问题:当你运行过log4j日志后,再去运行jul日志,你会发现jul日志变成了log4j的形式,并且还会报一个jar包冲突问题,这是为什么呢?
原因是:JCL动态查找机制进行日志实例化,执行顺序为:common-logging.properties--->系统环境变量--->log4j--->jul--->simplelog--->noplog
前面两个都没有找到,只找到了log4j的配置文件,所以我们要添加配置文件指定其为Jul的日志属性
3、在resources下创建jul日志的配置文件:commons-logging.properties
org.apache.commons.logging.Log = org.apache.commons.logging.impl.Jdk14Logger
7.3、通过日志门面实现
开发标准:记录日志不能直接使用日志实现框架,必须通过日志门面来实现
在以前,我们都是直接使用日志如log4j来当日志的,但这在日后对日志转换会非常的麻烦,使以现在日志的使用需要两部分:
日志 + 门面;比如说log4j:log4j(实现)+slf4j(门面) 必须加上桥接器!
实操:
这里创建两个类,两个类分别代表两个项目,一个使用log4j一个使用jul日志
在创建Logger的时候要注意导的包是否是对的,
Jul的包是import java.util.logging.Logger;
log4j的包是import org.apache.log4j.Logger;
7.3.1、log4j(实现)+slf4j(门面)
1、添加slf4j的核心依赖
<!--slf4j依赖,-slf4j core 使用slf4j必须添加,这是slf4j日志门面,基本上为接口-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
2、添加slf4j 到log4j的桥接器
7.1下的图可以看到slf4j到不同日志文件所对应的桥接器
<!--添加slf4j -log4j的桥接器-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>
3、通过日志门面来产出logger
//Log4j日志
public class Log4jMain {
public static void main(String[] args){
Logger logger = LoggerFactory.getLogger(Log4jMain.class);
System.out.println(logger.getClass());
logger.info("这是Log4j日志文件的输出");
}
}
Logger导入的包是import org.slf4j.Logger;
4、运行项目查看日志
可以看到日志文件是可以输出的。
7.3.2、Jul(实现)+JCL(门面)
1、前面以及添加slf4j的依赖,这里就不用添加了,slf4j 绑定JUL桥接jar包
<!--日志门面依赖-->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
2、通过日志门面来接收LogFactory的信息
//Jul日志
public class JulMain {
public static void main(String[] arge){
Logger logger = LoggerFactory.getLogger(JulMain.class);
System.out.println(logger.getClass());
logger.info("这是Jul日志文件的输出");
}
}
3、日志输出
7.4、日志转换
将jcl项目日志直接通过适配器统一到log4j日志上,且不用修改代码
添加jcl-over-slf4j依赖即可
<!--为了日志统一实现,将jcl转化到log4j
添加JCL-SLF4J的适配器
-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.36</version>
</dependency>
7.5、Logback日志集成
小结:
-
SpringBoot底层也是使用slf4j+logback的方式进行日志记录
-
logback桥接:logback-classic
-
-
SpringBoot也把其它的日志都替换成了slf4j
-
log4j适配:log4j-over-slf4j
-
jul适配:jul-to-slf4j
-
这两个适配器都是为了适配Spring的默认日志:jcl
-
7.6、SpringBoot日志使用
日志级别:
TRACE,DEBUG,INFO,WARN,ERROR或FATAL,OFF
测试:
//@Log4j2 可以直接通过lombok的注解,就不用声明日志记录器了,但不推荐
public class log {
//1、声明日志记录器
static Logger logger = LoggerFactory.getLogger(log.class);
public static void main(String[] args){
SpringApplication.run(log.class,args);
logger.trace("跟踪");
logger.debug("调试");
logger.info("信息");
logger.warn("警告");
logger.error("异常");
}
}
输出信息:
查看输出的信息,发现只输出到INFO这个级别,这就说明了springboot默认的日志级别为INFO
7.6.1、修改日志等级
在配置文件内修改:
logging:
level:
com:
wen: trace
这里的意思是,将指定文件的日志登机输出到设置的等级那里,比如这里是输出到trace
7.6.2、日志格式
详细介绍:
-
2022-04-17 10:04:11.399
-
日期和时间:毫秒精度,易于排序
-
-
TRACE
-
日志级别:ERROR,WARN,INFI,DEBUG或TRACE
-
-
28600
-
进程ID
-
-
分隔符 ---
-
一个---分离器来区分实际日志消息的开始
-
-
[main]
-
线程名称:用方括号括起来(对于控制台输出可能会被截断)
-
-
com.wen.log
-
记录日志的类
-
-
:跟踪
-
日志消息
-
7.6.3、文件输出
默认情况下,springboot仅记录到控制台,不会写日志文件。如果除了控制台输出外还想写日志文件,则需要设置一个logging.file.name或logging.file.path属性
下表显示的是logg.*的差别
logging.file.name | logging.file.path | 实例 | 描述 |
---|---|---|---|
no | no | 仅控制台记录 | |
指定文件名 | no | my.log | 写入指定的日志文件 |
no | 具体目录 | /var/log | 写入spring boot指定的目录 |
-
logging.file.name
-
可以设置文件的名称,如果没有设置路径会默认在项目的相对路径下,可以指定路径+文件名
-
logging:
level:
com:
wen: trace
file:
name: E:\Learning\Springboot\Demos\SpringBoot_Parent\SpringBoot_Log3\springboot_log3.log
-
logging.file.path
-
不可以指定文件名称,必须要指定一个物理文件夹路径,默认使用spring.log
-
logging:
level:
com:
wen: trace
file:
path: E:\Learning\Springboot\Demos\SpringBoot_Parent\SpringBoot_Log3
7.6.4、切换日志框架
将logback切换成log4j2
1、将logback的场景启动器排除,因为slf4j只能运行1个桥接器
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions> <!-- 去掉springboot自带的日志 -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
不排除就会出现以下错误:
2、添加log4j2的场景启动器
<!--log4j2的场景启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
3、添加log4j2配置文件
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="OFF">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="[%d{yyyy-MM-dd;HH:mm:ss.SSS Z}] [%-5p] [%t] [%c] %m%n"></PatternLayout>
</Console>
</Appenders>
<Logger name="com.wen" level="TRACE"/>
<Loggers>
<root level="info">
<appender-ref ref="Console"/>
</root>
</Loggers>
</Configuration>
运行成功!