slf4j-api —— 日志门面(核心)
是什么
-
slf4j-api是 SLF4J 的核心接口包 -
只定义接口,不包含任何具体日志实现
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
作用
-
提供统一的日志 API
-
让业务代码不依赖具体日志实现(Logback / Log4j2 / JUL 等)
-
实现 面向接口编程
特点
|
特性 |
说明 |
|---|---|
|
是否包含实现 |
❌ 否 |
|
是否可单独使用 |
❌ 否 |
|
是否必须引入 |
✅ 是 |
所有 SLF4J 项目都必须引入
*-over-slf4j —— “日志桥接器”(偷天换日)
这类 jar 的共同点是:
把别的日志框架的调用,偷偷转发给 SLF4J
它们通常用于 遗留系统 / 第三方依赖。
jul-to-slf4j(Java Util Logging → SLF4J)
解决什么问题
-
JDK 自带的日志:
java.util.logging(JUL) -
很多 JDK 内部或老代码在用
作用
-
将
java.util.logging.Logger的输出桥接到 SLF4J
使用方式
需要显式安装桥接 handler
SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();
特点
|
项目 |
说明 |
|---|---|
|
自动生效 |
❌ 否 |
|
性能损耗 |
✅ 有一定 |
|
是否常用 |
✅ 中等 |
常见于 JDK 原生日志较多的系统
一句话总结
|
组件 |
一句话解释 |
|---|---|
|
slf4j-api |
日志门面接口 |
|
jcl-over-slf4j |
JCL → SLF4J |
|
jul-to-slf4j |
JUL → SLF4J |
|
log4j-over-slf4j |
Log4j1 → SLF4J |
除了slf4j-api,都是转发的作用,为什么有的用to,有的用over呢?
|
命名 |
本质区别 |
|---|---|
|
|
“转接”:从 A 转到 SLF4J(通常较轻量) |
|
|
“覆盖”:用同名类直接盖掉原来的实现 |
为什么 JUL 用 to,而 JCL / Log4j 用 over?
jul-to-slf4j—— 为什么是 to?
原因 1:JUL 无法被“覆盖”
-
java.util.logging是 JDK 内置包 -
你不能在 classpath 里放一个:
java.util.logging.Logger会被 JVM 拒绝(安全管理 + 类加载机制)
原因 2:只能通过 Handler 转接
-
SLF4J 的做法是:
-
给 JUL 注册一个
Handler -
在 Handler 里把日志事件转发给 SLF4J
-
SLF4JBridgeHandler.install();
本质是:
JUL → Handler → SLF4J
所以是 to(转过去)
jcl-over-slf4j/ log4j-over-slf4j—— 为什么是 over?
原因 1:这些日志框架是“外部 jar”
-
Apache Commons Logging
-
Log4j 1.x
它们都在 应用 classpath 中,可以被覆盖。
原因 2:SLF4J 使用了“类级覆盖”
以 jcl-over-slf4j为例:
org.apache.commons.logging.Log
org.apache.commons.logging.LogFactory
SLF4J 提供了一个 一模一样的包名 + 类名
JVM 类加载时:
-
先加载到的是 SLF4J 的版本
-
原有实现直接“被架空”
本质是:
旧日志 API → 同名类 → SLF4J
所以是 over(盖在上面)
从“侵入性”理解 to vs over
|
维度 |
to |
over |
|---|---|---|
|
是否替换原有类 |
❌ 否 |
✅ 是 |
|
是否修改原框架行为 |
❌ 很少 |
✅ 完全接管 |
|
是否依赖类加载顺序 |
❌ 否 |
✅ 是 |
|
风险 |
低 |
中 |
|
典型代表 |
jul-to-slf4j |
jcl-over-slf4j |
判断该用哪个
问自己一个问题:
这个日志框架的类,我能自己在 classpath 里“重写”吗?
-
能 →
xxx-over-slf4j -
不能 →
xxx-to-slf4j
转载自CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/zlpzlpzyd/article/details/161052000



