java log4j api_Java日志框架——JCL(Log4J,Java Logging API )转SLF4J

本文介绍了如何在不改变原有代码的情况下,将基于JCL, Log4J或Java Logging API的日志框架转换为使用SLF4J。通过jcl-over-slf4j, log4j-over-slf4j和jul-to-slf4j这三个转换工具,详细阐述了转换过程和原理,并提供了具体示例。" 129686881,17719877,JAVA SSM 实验室设备管理系统设计与实现,"['JAVA', '课程设计', 'mybatis']
摘要由CSDN通过智能技术生成

一、应用场景

有很多以前的项目采用JCL,Log4J,Java Logging API等作为日志框架,现在如果想改成使用流行的SLF4J日志框架,但是不能改变项目代码,该如何做?

这就是jcl-over-slf4j(针对的是原来使用JCL),log4j-over-slf4j(针对的是原来使用Log4J),jul-to-slf4j(针对的是原来使用Java Logging API)等转换方案产生的原因所在。

二、基本原理

其实基本原理非常简单,以“本来使用JCL,现在想使用SLF4J”的项目A为例进行说明。

本来A中加载了对JCL的依赖(可以是"commons-logging:commons-logging"或者"commons-logging:commons-logging-api"),JCL相关类(比如“org.apache.commons.logging.Log”和“org.apache.commons.logging.LogFactory”等)由JCL依赖包提供,而如果我们现在在A中排除掉对JCL的依赖,而加载对jcl-over-slf4j的依赖(“org.slf4j:jcl-over-slf4j”),在jcl-over-slf4j的依赖中会提供上述JCL相关类的定义(注意两者的全限定名完全一致),jcl-over-slf4j的依赖中提供的这些JCL相关类会返回一个适配器类实例,该适配器类实例中包含一个org.slf4j.Logger类实例,现在项目A中的日志操作会被委托给该适配器类实例,而适配器类实例又会将日志操作委托给org.slf4j.Logger类实例。

根据以上论述,在A的类路径中,不能同时包含对JCL的依赖和对jcl-over-slf4j的依赖,这会导致存在两处地方提供JCL相关类的定义。如果最后使用了JCL依赖提供的JCL相关类的定义,那么转换就不会成功。

三、三种情况下的具体例子

3.1、jcl-over-slf4j

现在有一个项目,本来使用JCL,现在想使用SLF4J,代码片段如下:

import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;

public class Main {

public static void main(String[] args) {

Log log = LogFactory.getLog(Main.class);

log.error("Hello World");

System.out.println(log.getClass());

}

}1)本来的pom.xml如下:

commons-logging

commons-logging

1.1

log4j

log4j

1.2.17

现在的pom.xml如下:

org.slf4j

jcl-over-slf4j

1.7.12

org.slf4j

slf4j-api

1.7.12

ch.qos.logback

logback-classic

1.0.13

2)运行结果如下:

0818b9ca8b590ca3270a3433284dd417.png 3)运行过程

JCL相关类由jcl-over-slf4j提供,查看源码可以发现,jcl-over-slf4j提供的JCL相关类最后返回一个“org.apache.commons.logging.impl.SLF4JLocationAwareLog”(继承“org.apache.commons.logging.Log”接口)适配器类实例A,A中包含一个“ch.qos.logback.classic.Logger”(继承“org.slf4j.Logger”接口)实例B,A被赋值给log对象,现在通过log对象进行的日志操作,会依次委托给A实例,B实例进行。

3.2、log4j-over-slf4j

现在有一个项目,本来使用Log4J,现在想使用SLF4J,代码片段如下:

import org.apache.log4j.Logger;

public class Main {

public static void main(String[] args) {

Logger logger = Logger.getLogger(Main.class);

logger.error("Hello World");

System.out.println(logger.getClass());

}

}1)本来的pom.xml如下:

log4j

log4j

1.2.17

现在的pom.xml如下:

org.slf4j

log4j-over-slf4j

1.7.12

org.slf4j

slf4j-api

1.7.12

ch.qos.logback

logback-classic

1.0.13

2)运行结果如下:

0818b9ca8b590ca3270a3433284dd417.png

3)运行过程

Log4J相关类由log4j-over-slf4j提供,查看源码可以发现,log4j-over-slf4j提供的Log4J相关类最后返回一个"org.apache.log4j.Logger"(此类是"org.slf4j:log4j-over-slf4j"提供的,跟"log4j:log4j"提供的"org.apache.log4j.Logger"不一样,此类含有一个"org.slf4j.Logger"实例对象,因而该类的身份是一个适配器类)适配器类实例A,A中包含一个"ch.qos.logback.classic.Logger"(继承"org.slf4j.Logger"接口)实例B,A被赋值给logger对象,现在通过logger对象进行的日志操作,会依次委托给A实例,B实例进行。

3.3、jul-to-slf4j

现在有一个项目,本来使用Java Logging API,现在想使用SLF4J,代码片段如下:

import java.util.logging.Logger;

public class Main {

public static void main(String[] args) {

Logger logger = Logger.getLogger("Main");

logger.info("Hello World");

System.out.println(logger.getClass());

}

}

1)本来的pom.xml如下:

现在的pom.xml如下:

org.slf4j

jul-to-slf4j

1.7.12

org.slf4j

slf4j-api

1.7.12

ch.qos.logback

logback-classic

1.0.13

2)运行结果如下:

0818b9ca8b590ca3270a3433284dd417.png

3)运行过程

Java Logging API相关类由JDK提供,我们不能排除掉JDK,因而,在"Java Logging API转SLF4J"过程中采用的转换方案跟"JCL转SLF4J"和"Log4J转SLF4J"采用的转换方案不同,具体思路是以jul-to-slf4j提供的"org.slf4j.bridge.SLF4JBridgeHandler"替换掉Java Logging API使用的Handler(Handler即是Appender),Java Logging API原来使用的Handler将日志输出到Console,文件,数据库等,现在"org.slf4j.bridge.SLF4JBridgeHandler"将日志输出到SLF4J日志框架。简单来说,就是将原本Java Logging API的日志输出重定向到SLF4J日志框架。

Java Logging API的默认配置文件路径为:JDK_HOME/jre/lib/logging.properties,根据以上说明,需要修改“handlers”属性值,修改后"handlers"属性的内容如下:

handlers= org.slf4j.bridge.SLF4JBridgeHandler 参考文献: [1]http://www.slf4j.org/legacy.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值