SLF4J 中的适配器模式

什么是适配器模式

适配器模式中,适配器包装不兼容指定接口的对象,来实现不同兼容指定接口。

SLF4J 中的适配器模式

SLF4J 是一个日志门面系统,其中提供了统一的 Logger 等接口,许多框架都会面向 SLF4J 打印日志,这样就不会和具体的日志框架耦合在一起,框架使用者也就能够很方便地在不同日志实现之间切换。

SLF4J 出现之前,已经有 Log4j 等日志框架了,其本身有一套 Logger 之类的接口,为实现和 SLF4J 兼容,就引入了对应适配器层 slf4j-log4j12。

首先看一下 SLF4J 中的 Logger 接口:

public interface Logger {
String getName();
void debug(String msg);
void info(String msg);
void warn(String msg);
void error(String msg);
// ...省略其他方法
}

而待适配的 Log4j 的 Logger 部分源码如下:

public class Logger extends Category {
protected Logger(String name) {
super(name);
}
public static Logger getLogger(String name) {
return LogManager.getLogger(name);
}
public static Logger getLogger(Class clazz) {
return LogManager.getLogger(clazz.getName());
}
public static Logger getRootLogger() {
return LogManager.getRootLogger();
}
public static Logger getLogger(String name, LoggerFactory factory) {
return LogManager.getLogger(name, factory);
}
public void trace(Object message) {
if (!this.repository.isDisabled(5000)) {
if (Level.TRACE.isGreaterOrEqual(this.getEffectiveLevel())) {
this.forcedLog(FQCN, Level.TRACE, message, (Throwable)null);
}
}
}
// ...省略部分方法
}

其继承的 Category 类中有 debug、info 等方法。其核心方法为 log:

public void log(String callerFQCN, Priority level, Object message, Throwable t) {
if(repository.isDisabled(level.level)) {
return;
}
if(level.isGreaterOrEqual(this.getEffectiveLevel())) {
forcedLog(callerFQCN, level, message, t);
}
}

下面再看适配器类 Log4jLoggerAdapter,它先是继承了 MarkerIgnoringBase,MarkerIgnoringBase 实现了 Logger,等于说 Log4jLoggerAdapter 实现了 Logger:

public final class Log4jLoggerAdapter extends MarkerIgnoringBase implements LocationAwareLogger, Serializable {
private static final long serialVersionUID = 6182834493563598289L;
final transient org.apache.log4j.Logger logger;
Log4jLoggerAdapter(org.apache.log4j.Logger logger) {
this.logger = logger;
this.name = logger.getName();
traceCapable = isTraceCapable();
}
public void debug(String msg) {
logger.log(FQCN, Level.DEBUG, msg, null);
}
public void info(String msg) {
logger.log(FQCN, Level.INFO, msg, null);
}
// ...省略部分方法
}

Log4jLoggerAdapter 的构造方法接收 org.apache.log4j.Logger 类型的对象,其 debug 等方法的实现中,将具体的打印工作委托给 Log4j Logger。

如果 Log4j 和 SLF4J 正常整合,则 SLF4J 的 LoggerFactory.getLogger 方法最终会返回 Log4jLoggerAdapter 的实例,从而使 Log4j 和 SLF4J 兼容。

下面是类图:

img

参考:slf4j 中有典型适配器模式,不看一看?

posted @   Higurashi-kagome  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
历史上的今天:
2022-10-26 IDEA 跳到定义或使用
2021-10-26 AutoLISP command 命令中的 _.line line -line 有什么区别
点击右上角即可分享
微信分享提示