简单日志门面(Simple Logging Facade For Java)
SLF4J主要是为了给Java日志访问提供一套标准、规范的API框架,
其主要意义在于提供接口,具体的实现可以交由其他日志框架,如log4j、logback、log4j2。
对于一般的Java项目而言,日志框架会选择slf4j-api作为门面,配上具体的实现框架,中间使用桥接器完成桥接。
所以我们可以得出SLF4J最重要的两个功能就是对于日志框架的绑定以及日志框架的桥接。
org.slf4j
slf4j-api
1.7.21
org.slf4j
slf4j-log4j12
1.7.21
Logger logger = LoggerFactory.getLogger(Slf4jAndLog4j.class);
logger.info("this is slf4j&log4j test:{}",123);
log4j的配置文件参见:log4j日志框架的使用-CSDN博客
ch.qos.logback
logback-classic
1.1.7
Logger logger = LoggerFactory.getLogger(Slf4jAndLogback.class);
logger.info("this is slf4j&logback test:{}",123);
logback配置参见:logback日志框架使用-CSDN博客
org.slf4j
slf4j-api
1.7.25
org.apache.logging.log4j
log4j-slf4j-impl
2.12.1
org.apache.logging.log4j
log4j-core
2.12.1
Logger logger = LoggerFactory.getLogger(Slf4jAndLog4j2.class);
logger.info("this is slf4j&log4j2 test:{}",123);
log4j2的配置参见:log4j2日志框架使用-CSDN博客
代码解析入口:
LoggerFactory.getLogger(Slf4jAndLog4j2.class);
该段代码会寻找依赖中的日志实现
如何寻找日志依赖?
org.slf4j.LoggerFactory#findPossibleStaticLoggerBinderPathSet方法会读取依赖中所有的org.slf4j.impl.StaticLoggerBinder类所在的文件路径
在工作路径下,依赖下寻找文件名为:org/slf4j/impl/StaticLoggerBinder.class的文件。其实说白一点,就只寻找各个日志框架的桥接引导类org.slf4j.impl.StaticLoggerBinder,如下是各个日志框架实现的桥接截图:
寻找到对应的日志框架桥接的引导类之后,调用初始化操作完成日志的加载和初始化动作。这就是slf4j门面模式和各日志框架实现的原理
在前面的关于log4j的源码浅析(log4j日志框架的使用-CSDN博客)中,log4j的初始化LogManager类中完成的。slf4j的桥接器(StaticLoggerBinder)引导完成初始化加载
log4j2的引导操作截图如下:
在前面的关于log4j2的源码浅析(log4j2日志框架使用-CSDN博客)中,log4j2的入口是LogManager的静态代码块加载。slf4j的桥接器(StaticLoggerBinder)引导完成初始化加载
logback的引导操作可以翻看前面的文章:logback日志框架使用-CSDN博客
引用一张log4j2的官方性能压测数据图:
log4j2的异步日志性能明显高于log4j和logback(由于日志框架出现的时间有先后,后面的日志肯定会规避前面日志框架的缺点而继承其优点)
log4j2全异步日志开启
1 引入依赖
com.lmax
disruptor
3.4.2
2 增加启动参数
-Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
或者
System.setProperty("Log4jContextSelector", "org.apache.logging.log4j.core.async.AsyncLoggerContextSelector")
平时在使用slf4j门面日志配合其他日志框架时,很少会在类中通过编码定义Logger对象,而习惯性的使用@slf4j注解完成Logger定义。不知道大家想过没有,这个注解是如何实现的?
@slf4j注解是由lombok
依赖引入的,该依赖会将标注了@slf4j的类编程成形如:
private static final Logger log = LoggerFactory.getLogger(Demo2.class);
的一个log对象
源代码如下:
编译之后的类: