一、常见的日志框架
具体日志实现框架:
- Log4j
- log4j2
- logback
- jul (java.util.logging)
- simpleLog
- 其他 日志门面(抽象):
- jcl (commons-logging)
- slf4j (Simple Logging Facade for JAVA)
- log4j2 也支持门面模式
目前市面比较流行的主要是log4j2 和logback、slf4j了
常用的搭配有:
- commons-logging + log4j 这种基本已经被淘汰
- slf4j + logback 目前的主流
- log4j-api + log4j-core
- slf4j + log4j-core
二、JCL 的介绍
maven 引入
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
用法:
public void jcl(){
Log logger = LogFactory.getLog("jcl");
logger.info("jcl");
}
核心代码: 目前JCL 内置的4中日志。
private static final String[] classesToDiscover = {
LOGGING_IMPL_LOG4J_LOGGER,
"org.apache.commons.logging.impl.Jdk14Logger",
"org.apache.commons.logging.impl.Jdk13LumberjackLogger",
"org.apache.commons.logging.impl.SimpleLog"
};
JCL全称jarkartConnons-logging 可以统一编程,因为他是抽象的,可以根据用户提供的具体日志技术去实例化具体的对象,所以一定程度上可以解决不同日志的问题;JCL的原理是内置了一个字符串数组,这个数组当中保存了类名; 在调用getLogger方法去实例化一个logger对象的时候会遍历这个数组,从这个数组当中拿到类目如果 能够通过class.forName加载到说明用户配置了该日志技术,从而使用该日志技术。
缺点: 内置的数组属于硬编码、并且数量有限只能解决小部分日志问题、无法解决在使用JCL之前遗留 的问题;最大的问题是他没有更新了
目前已基本废弃。 JCL 原理图
三、slf4j 介绍
SLF4J全称 Simple Logging Facade for JAVA ,是通过绑定器来和具体日志框架工作的。 maven 引入:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.32</version>
</dependency>
示例代码:
public void slf4j(){
Logger logger = LoggerFactory.getLogger("slf4j");
logger.error("slf4j");
}
下面重点介绍下 SLF4J 的工作原理,如图:
官网扒下来的图 (www.slf4j.org/manual.html…
优点: 统一编程方式,假如有新的日志框架出现可以发布新的绑定器来实现拓展,也就是增加新的绑定器jar包即可,程序员引入新的绑定器jar即可实现转换。
缺点:无法解决历史硬编码问题
硬编码问题?什么是硬编码问题?怎么解决硬编码的问题呢 ?
例如 这种直接使用 log4j 的打印,没有使用任何日志门脸框架
import org.apache.log4j.Logger;
/**
* @Author
* @Date 2022/1/6 11:29
*/
public class MyApp {
static Logger logger = Logger.getLogger(MyApp.class);
public static void main(String[] args) {
logger.info("这是org.apache.log4j.Logger 日志打印");
}
}
那slf4j 是怎么解决这种硬编码问题的呢?
slf4j 引入一个新的概念 -- 桥接器
桥接器工作原理:
相关依赖坐标解释
<!-- log4j1 核心-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- jcl 核心-->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<!-- logback-绑定器 包含了核心和slf4j 以及logback的绑定器 三个 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.4</version>
</dependency>
<!-- slf4j-api 核心-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.32</version>
</dependency>
<!-- slf4j-log4j1 绑定器-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.32</version>
</dependency>
<!-- log4j2-slf4j-impl 绑定器 绑定log4j2 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.13.3</version>
</dependency>
<!-- log4j2桥接器-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
<version>2.9.1</version>
</dependency>
<!-- log4j-over-slf4j log4j1的桥接器 不能和log4j1的核心共存会有jar冲突问题 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>1.7.32</version>
</dependency>
<!-- log4j2 核心-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.13.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.13.2</version>
</dependency>
四、 总结
1.slf4j 已成主流,一统天下
2.兼容硬编码是它优于其他框架的显著优势。