个人结合学习视频做一个简单理解、记录
slf4j日志门面具体使用哪个日志实现,看的是pom文件中导入依赖的顺序,谁在前面就使用谁作为日志实现
核心--slf4j依赖
<!--slf4j 核心依赖--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency>
1.入门案例
在没有集成其他日志框架的基础上,slf4j使用自带的日志框架slf4j-simple,依赖也要单独引入
<!--slf4j 自带的简单日志实现 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>1.7.25</version> </dependency>
显示效果
1.1 还可以动态输出日志信息,更加的灵活,通过以占位符的形式来代替字符串拼接
Logger logger = LoggerFactory.getLogger(SLF4JTest01.class); String name = "zs"; int age = 23; //{},这个括号就是占位符 logger.info("学生信息-姓名:"+name+";年龄:"+age); logger.info("学生信息-姓名:{},年龄:{}",new Object[]{name,age}); logger.info("学生信息-姓名:{},年龄:{}",name,age);
显示的日志信息
2.在集成第三方日志框架前,看一眼slf4j的官网图
2.1 slf4j日志门面有3共情况对日志实现进行绑定
1.在没有绑定任何日志实现的基础上,日志门面不能够实现任何的功能,slf4j-simple是slf4j官网提供的日志实现,导入依赖后,自动绑定到slf4j日志门面上,如果不导入将不提供任何实现。
2.logback和simple(包括nop),都是slf4j日志门面时间线后面提供的日志实现,所以完全遵循slf4j进行设计,只需要导入依赖,就可以无缝衔接,其中nop的作用是禁止所以日志的打印。
3.log4j和JUL,都是slf4j日志门面时间线前面的日志实现,所以API不遵循slf4j进行设计,可以通过适配桥接的技术,完成与日志门面的衔接。
logback依赖
<!-- logback依赖 --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency>
nop依赖
<!-- 导入nop -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>1.7.25</version>
</dependency>
//--------------------------分割线----------------------------------------------------------
logback,simple,nop,属于在slf4j日志门面技术出现之后,所以只需要直接导入依赖就能使用。
3.此时,如果需要使用log4j日志实现,我们需要用到桥接的技术,绑定一个适配器,要导入两个依赖才能实现功能
适配器的依赖和log4j的依赖
<!-- 导入log4j适配器依赖 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.25</version> </dependency> <!-- 导入log4j依赖 --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
还需要加入log4j的配置文件
#配置根节点logger log4j.rootLogger=trace,console log4j.appender.console=org.apache.log4j.ConsoleAppender log4j.appender.console.layout=org.apache.log4j.PatternLayout log4j.appender.console.layout.conversionPattern=[%-10p]%r %c%t%d{yyyy-MM-dd HH:mm:ss:SSS} %m%n
日志显示信息
4. JUL日志实现--属于slf4j时间线之前的日志实现,需要加入适配器依赖,JUL因为是JDK内置的,所以不用手动导入依赖了
<!--导入JUL的适配器依赖,因为JUL是JDK内置的,所以不用导入JUL的依赖--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-jdk14</artifactId> <version>1.7.25</version> </dependency>
日志显示信息
备注:当出现红色框的这类警告信息时,说明导入了多种日志实现方式,但是默认只使用一种(按顺序的第一个),注释掉就没有显示了。但是在真实的生产环境中,一般只绑定一种日志实现,绑定多个会出现多余的警告信息。
5. demo
需求:项目当中使用的是log4j,现在log4j不能满足项目的需求了,需要重构为slf4j+logback,在不改变代码的前提下解决这个问题。
5.1 注释掉log4j,此时代码肯定是报错的,然后我们加入slf4j和logback的依赖,再加入一个桥接器的依赖,桥接器解决的是项目中的日志重构问题,当项目中存在之前的日志API,可以通过桥接器转换到slf4j的实现。
<!--slf4j 核心依赖--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency> <!--桥接器--> <dependency> <groupId>org.slf4j</groupId> <artifactId>log4j-over-slf4j</artifactId> <version>1.7.25</version> </dependency> <!-- logback依赖 --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency>
未重构前的日志信息
重构后的日志信息
在重构之后,会造成一种假象,使用的明明是log4j包下组件资源,但是真正的日志实现,是slf4j门面+logback日志实现,这就是桥接器带来的效果。
注意:
桥接器加入后,适配器就没有必要加入了
桥接器和适配器不能同时加入
桥接器在适配器的上方,则运行报错
桥接器在适配器的下方,则不会执行桥接器,没有意义